前面三章主要讲解了RxJava的部分内容,而作为Android开发者就不得不提到将RxJava和Android结合起来应用的框架---RxAndroid。
RxAndroid是RxJava的扩展,包含了一些针对Android的特殊绑定。
1 AndroidSchedulers 它为Android线程机制提供了现成的schedulers。如果希望在UI线程上执行一些代码只管用AndroidSchedulers.mainThread()。
retrofitService.getImage(url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bitmap -> myImageView.setImageBitmap(bitmap));
2 AndroidObservable 它提供了在Android生命周期内的一些功能。比如bindActivity() 和 bindFragment(),它们会自动让观察者在AndroidSchedulers.mainThread()主线程执行,并且会在离开activity或fragment时自动停止释放数据。
AndroidObservable.bindActivity(this, retrofitService.getImage(url))
.subscribeOn(Schedulers.io())
.subscribe(bitmap -> myImageView.setImageBitmap(bitmap);
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
AndroidObservable.fromBroadcast(context, filter)
.subscribe(intent -> handleConnectivityChange(intent));
4 ViewObservable 它针对于View,监听点击事件可以用ViewObservable.clicks(),监听TextView的内容变化可以用ViewObservable.text()。
ViewObservable.clicks(mCardNameEditText, false)
.subscribe(view -> handleClick(view));
Retrofit
回调使用:
@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);
Rx使用:
@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);
如果我们第一个请求是获取图片,第二个请求是获取图片信息,那么如今我们可以将这两次请求进行合并:
Observable.zip(
service.getUserPhoto(id),
service.getPhotoMetadata(id),
(photo, metadata) -> createPhotoWithData(photo, metadata))
.subscribe(photoWithData -> showPhoto(photoWithData));
生命周期
我把难点留到了最后,即如何处理activity的生命周期。有两个老生常谈的问题:
1 在configuration改变的时候持续Subscription(比如屏幕翻转)。
2 因Observable内持有context引用引发的内存泄漏问题。
尽管没有标准答案,但有些思路可以参考。
第一个问题,缓存一份请求,在activity重建后再次被订阅,而在此之前需要先解绑上一次被订阅的观察者:
Observable<Photo> request = service.getUserPhoto(id).cache();
Subscription sub = request.subscribe(photo -> handleUserPhoto(photo));
// ...When the Activity is being recreated...
sub.unsubscribe();
// ...Once the Activity is recreated...
request.subscribe(photo -> handleUserPhoto(photo));
第二个问题,重点在于管理subscription,即合适的解绑订阅,那么通常的做法就是CompositeSubscription,添加进所有的subscription然后在适当的时候一次性解绑:
private CompositeSubscription mCompositeSubscription
= new CompositeSubscription();
private void doSomething() {
mCompositeSubscription.add(
AndroidObservable.bindActivity(this, Observable.just("Hello, World!"))
.subscribe(s -> System.out.println(s)));
}
@Override
protected void onDestroy() {
super.onDestroy();
mCompositeSubscription.unsubscribe();
}
当然这个操作可以放到基类去处理,子类只需要继承就可以了,但是要注意的是一旦解绑之后,要重用时就必须要新建一个 CompositeSubscription。
基础教学到此结束,重点在于数据链和操作符的理解。