此前对rxjava的诸多用法小小的进行过总结,rxjava的使用给代码设计带来了很多惊奇和方便。但是在了解到PublishSubject之后再次被rxjava的简便给折服了。在介绍PublishSubject之前,先容我给出这样一个命题,在Android的开发中,我们经常会在Service中处理批量下载的任务,然后将下载的进度显示在Activity中。如果需要完成Service中数据的更新到Activity数据的显示,可行的方案有哪些。
目前能够列举到的方案有如下:
1. DataBinding
2. 广播
3. EventBus
4. Rxjava的PublishSubject
这些方案中DataBinding,网上关于它的介绍不俗,但是我看实现中用起来还是有点麻烦,或许是我没有深入的了解和使用,它不是本文要介绍的重点。广播在使用中需要编写注册,解除注册的代码以及相关的BroadcastReceiver代码,代码量感觉小小的有点大。EventBus比广播要好一点点,但是同样需要注册EventBus和取消注册EventBus,只是可以通过注解来指定完成事件响应的函数。Rxjava的PublishSubject在设计中省去了注册和取消注册的逻辑,比广播和EventBus更高一筹。
以命题中介绍的Service进行批量下载,在Service中更新数据和Activity中显示数据为例来介绍Rxjava的PublishSubject的使用。
/** *Service部分的代码逻辑 **/ import rx.Observable; import rx.functions.Action1; import rx.schedulers.Schedulers; import rx.subjects.PublishSubject; public class DownLoadService extends Service { ... private static final PublishSubject<DownloadInfo> EVENT_PUBLISH_SUBJECT = PublishSubject.create();//构造一个PublishSubject /** *提供对外的PublishSubject **/ public static Observable<DownloadInfo> getStatusObservable() { return EVENT_PUBLISH_SUBJECT.onBackpressureLatest();//此处采用Rxjava背压防止事件发生过快 } /** *对外发布下载更新的数据 **/ private void updateDownloadStatus(DownloadInfo downloadInfo) { ... EVENT_PUBLISH_SUBJECT.onNext(chapterInfo); ... }
Activity中的代码逻辑如下
import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.functions.Func1; import rx.schedulers.Schedulers; import rx.subjects.PublishSubject; public class DownloadActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { ... receiveCacheProgress(); ... } /** *从service中获取下载更新的数据 **/ private void receiveCacheProgress() { DownloadService.getStatusObservable().compose(this.<DownloadInfo>avoidStateLoss()) //rxlifecycle 防止Activity关闭带来的内存泄漏 .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<DownloadInfo>() { @Override public void call(DownloadInfo downloadInfo) { processProgress(downloadInfo); } }); } /** *对进度更新后的数据在一个recycleView中进行显示 **/ private void processProgress(DownloadInfo downloadInfo) { ... if (listAdapter != null) { listAdapter.updateProgress(downloadInfo); } ... } }
上述代码仅仅只写了Rxjava代码所需要编写的部分,从设计模式的角度出发,可以理解为在Service中定义了一个静态被观察者,并提供了这个被观察者的静态方法和触发这个被观察者事件,在Activity中获取这个被观察者后就进行订阅。省去了广播和Eventbus中很明显的需要注册和解除注册的环节,关于不解除注册可能带来的内存泄漏,在代码中已经使用rxlifecycle来进行解决了(rxlifecycle的相关介绍:https://blog.csdn.net/polo2044/article/details/80559390)
https://www.cnblogs.com/Jason-Jan/p/8017412.html
https://www.jianshu.com/p/428a5257839c
https://www.jianshu.com/p/6f1ea19a17ed