转载

Re Android初步探究(一)

上个星期看到 trello 招聘远程 android 工程师,其中 trello 说道他们是 RxJava 的重度用者。

RxJava ? 什么是 RxJava

RxJava 是 Reactivex 库的一个扩展。

Reactivex 又是什么? 官方是这样解释的:

ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.

It extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.

总结一下特点:

1、 函数响应式编程 (Functional Reactive Programming)简称 FRP

2、异步

3、事件驱动(事件作为可观察序列)

4、基于观察者模式

5、组合式

6、专门出错处理

7、适用于处理并发问题

RxAndroid 是 RxJava 的一个特别版,主要是提供了可设置计算的所在线程以及更新 UI 时可在主线程更新。

provides a Scheduler that schedules an Observable on a given Android Handler thread, particularly the main UI thread

provides base Observer implementations that make guarantees w.r.t. to reliable and thread-safe use throughout Fragment and Activity life-cycle callbacks (coming soon)

provides reusable, self-contained reactive components for common Android use cases and UI concerns (coming soon)

这块新大陆开垦的人少之又少,没猜错的话,大家几乎都是在看 Grokking RxJava 这四篇文章,其中第四篇 Grokking RxJava, Part 4: Reactive Android 就是讲 RxAndroid 的。虽然这篇文章是发表于 2014 年 10 月 8 日,但 RxAndroid 里面已经有很多改动,例如: AndroidObservable 变成 AppObservableViewObservable 的这个 text() 方法已经移到 WidgetObservable 这个类下面等等。

不过四篇文章的思想还是在的,变的只是类和方法的改动,所以不能直接拷贝代码到 IDE 里面去运行,不然都是报错,然后就怀疑这是什么鬼玩意啊,就不再深究下去了。

接下来我们来体验一番基于事件的函数响应式编程。我们来实现一个这样的一个需求,点击复选框,检查输入框是否为空,效果如图:

Re Android初步探究(一)

我们平时的话一般都是给这三个控件设置事件监控,声明一个复选框选中标识 flag,然后在监控控件的回调函数去判断,代码大概是这个样子:

checkButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  @Override  public void onCheckedChanged(CompoundButton compoundButton, boolean b) {   needCheck = b;   if(needCheck){    if(mEditText.getText().toString().equals("")){     okBtn.setEnabled(false);    }else{     okBtn.setEnabled(true);    }   }else{    okBtn.setEnabled(true);   }  } }); mEditText.addTextChangedListener(new TextWatcher() {  @Override  public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {  }  @Override  public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {   if(needCheck){    if(charSequence.toString().equals("")){     okBtn.setEnabled(false);    }else{     okBtn.setEnabled(true);    }   }  }  @Override  public void afterTextChanged(Editable editable) {  } }); okBtn.setOnClickListener(new View.OnClickListener() {  @Override  public void onClick(View view) {   Toast.makeText(MainActivity.this, mEditText.getText().toString(), Toast.LENGTH_SHORT).show();  } }); 

而我们使用 RxAndroid 的话,就是这个样子:

Observable<Boolean> needCheckObservable = WidgetObservable.input(checkButton, true).map(new Func1<OnCheckedChangeEvent, Boolean>() {  @Override  public Boolean call(OnCheckedChangeEvent onCheckedChangeEvent) {   return onCheckedChangeEvent.value();  } }); Observable<OnTextChangeEvent> editTextObservable = WidgetObservable.text(mEditText, true); Observable.combineLatest(needCheckObservable, editTextObservable, new Func2<Boolean, OnTextChangeEvent, Boolean>() {  @Override  public Boolean call(Boolean aBoolean, OnTextChangeEvent onTextChangeEvent) {   return aBoolean ? !TextUtils.isEmpty(onTextChangeEvent.text()) : true;  } }).observeOn(AndroidSchedulers.mainThread())   .subscribe(new Action1<Boolean>() {    @Override    public void call(Boolean aBoolean) {     okBtn.setEnabled(aBoolean);    }   }); ViewObservable.clicks(okBtn)   .observeOn(AndroidSchedulers.mainThread())   .subscribe(new Action1<OnClickEvent>() {    @Override    public void call(OnClickEvent onClickEvent) {     Toast.makeText(MainActivity.this, mEditText.getText().toString(), Toast.LENGTH_SHORT).show();    }   }); 

平时的方法,用了 45 行代码,用 RxAndroid 则是 29 行,那句什么话来着,less is more.

用代码行数去衡量一段代码的好坏? 似乎太庸俗,太傻 X 了,当然,我们不会这样去衡量。只是开个玩笑.

来,我们来看看上面的代码。

1、函数式表达2、基于事件的可组合模式(以上就是把复选框的选中事件和输入框的输入事件组合在一起)

上面的例子我没有理会错误的处理和完成的处理,其实我们还可以这样做:

ViewObservable.clicks(okBtn) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<OnClickEvent>() {  @Override  public void onCompleted() {  }  @Override  public void onError(Throwable e) {   Toast.makeText(MainActivity.this, " 哎呀,出错了 ", Toast.LENGTH_SHORT).show();  }  @Override  public void onNext(OnClickEvent onClickEvent) {   Toast.makeText(MainActivity.this, mEditText.getText().toString(), Toast.LENGTH_SHORT).show();  } }); 

专门有出错的处理回调。

上面的例子也没有体现出异步的功能,我们再来个例子,在输入框输入一个图片 url 然后去下载图片并显示:

ViewObservable.clicks(okBtn).map(new Func1<OnClickEvent, Bitmap>() {  @Override  public Bitmap call(OnClickEvent onClickEvent) {   return null;  } }) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<Bitmap>() {  @Override  public void onCompleted() {   Toast.makeText(MainActivity.this, " 图片加载完成 ", Toast.LENGTH_SHORT).show();  }  @Override  public void onError(Throwable e) {   Toast.makeText(MainActivity.this, " 哎呀,出错了 ", Toast.LENGTH_SHORT).show();  }  @Override  public void onNext(Bitmap bitmap) {   //show your bitmap  } }); 

体验到函数响应式编程的魅力了吗? 反正我已经上瘾了,这片新的技术等着你和我去探究。

现在研究这个的人实在太少了,很少能找到交流的人,也没搜到相关的交流群,我在这里建了一个群:16703352 , 有兴趣的同学可以加一加,大家一起来探究探究哦。

可能有同学发现了,以上说的都是函数式编程的好处,那它有不好的地方吗? 当然有啦。这个下次再来探讨,有点困了,又 12 点了,我的早睡好习惯呢。

PS:这块领域比较新,可参考的文献也较少,有,也是英文居多,本人精力有限,暂只能领会这么多,也难免有错误理解之处,如有,望帮忙校正,谢谢。

正文到此结束
Loading...