RxJava2 实战系列文章

RxJava2 实战知识梳理(1) – 后台执行耗时操作,实时通报 UI
更新
RxJava2 实战知识梳理(2) –
计算一段时间内数据的平均值
RxJava2 实战知识梳理(3) –
优化搜索联想功能
RxJava2 实战知识梳理(4) – 结合 Retrofit
请求新闻消息
RxJava2 实战知识梳理(5) –
简单和进阶的轮询操作
RxJava2 实战知识梳理(6) –
基于左类型的重试请求
RxJava2 实战知识梳理(7) – 基于 combineLatest
实现之输入表单验证
RxJava2 实战知识梳理(8) – 使用 publish + merge
优化先加载缓存,再念博网络数据的伸手过程
RxJava2 实战知识梳理(9) – 使用 timer/interval/delay
实现任务调度
RxJava2 实战知识梳理(10) – 屏幕旋转导致 Activity
重建时回升任务
RxJava2 实战知识梳理(11) –
检测网络状态并自行重试请求
RxJava2 实战知识梳理(12) – 实战讲解 publish & replay & share & refCount
& autoConnect
RxJava2 实战知识梳理(13) –
如何令错误产生时不活动终止订阅关系
RxJava2 实战知识梳理(14) – 在 token 过期时,刷新过期 token
并再次发起呼吁
RxJava2 实战知识梳理(15) – 实现一个略的 MVP + RxJava + Retrofit
应用


一、前言

接触RxJava2已经非常悠久了,也看了网上的诸多篇,发现中心还是当针对RxJava的着力思想介绍下,再失去对各个操作符进行剖析,但是关押了以后觉得了了不久纵记不清了。

偶的时机见到了开源项目
RxJava-Android-Samples,这里一起介绍了十六种RxJava2的运用状况,它从实质上的行使场景出发介绍RxJava2的用,特别适合对于RxJava2早已闹开摸底的开发者更是地失去学习怎么用那动及骨子里付出中。

所以,我打算跟着这类型之思路编写一名目繁多实战的介绍连就示范代码编写,并针对性拖欠实例中之所以到的文化进行介绍,做到学以致用。下面,就起来首先独例证的上学,源码的堆栈为:RxSample。

二、示例

2.1 应用场景

当我们用进行局部耗时操作,例如下载、访问数据库等,为了不封堵主线程,往往会以那坐落后台进行处理,同时于拍卖的长河中、处理完了后通报主线程更新UI,这里就干到了晚高线程和主线程之间的切换。首先想起一下,在原先我们一般会因此以下简单栽办法来兑现即同成效:

  • 创办一个初的子线程,在该run()主意中履行耗时的操作,并通过一个及主线程Looper关联的Handler出殡信息给主线程更新进度显示、处理结果。
  • 使用AsyncTask,在其doInBackground道吃实践耗时的操作,调用publishProgress计通知主线程,然后以onProgressUpdate遭遇更新快显示,在onPostExecute遭逢展示最终结果。

这就是说,让咱们看片以RxJava吃安完成就同样需求。

2.2 示例代码

咱的界面上闹一个按钮mTvDownload,点击后会倡导一个耗时的天职,这里我们之所以Thread.sleep来效仿耗时的操作,每隔500ms咱会用手上底快通报主线程,在mTvDownloadResult备受显当前处理的进度。

public class BackgroundActivity extends AppCompatActivity {

    private TextView mTvDownload;
    private TextView mTvDownloadResult;
    private CompositeDisposable mCompositeDisposable = new CompositeDisposable();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_background);
        mTvDownload = (TextView) findViewById(R.id.tv_download);
        mTvDownloadResult = (TextView) findViewById(R.id.tv_download_result);
        mTvDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startDownload();
            }
        });
    }

    private void startDownload() {
        final Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {

            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 100; i++) {
                    if (i % 20 == 0) {
                        try {
                            Thread.sleep(500); //模拟下载的操作。
                        } catch (InterruptedException exception) {
                            if (!e.isDisposed()) {
                                e.onError(exception);
                            }
                        }
                        e.onNext(i);
                    }
                }
                e.onComplete();
            }

        });
        DisposableObserver<Integer> disposableObserver = new DisposableObserver<Integer>() {

            @Override
            public void onNext(Integer value) {
                Log.d("BackgroundActivity", "onNext=" + value);
                mTvDownloadResult.setText("Current Progress=" + value);
            }

            @Override
            public void onError(Throwable e) {
                Log.d("BackgroundActivity", "onError=" + e);
                mTvDownloadResult.setText("Download Error");
            }

            @Override
            public void onComplete() {
                Log.d("BackgroundActivity", "onComplete");
                mTvDownloadResult.setText("Download onComplete");
            }
        };
        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(disposableObserver);
        mCompositeDisposable.add(disposableObserver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCompositeDisposable.clear();
    }
}

其实的运转结果如下:

其三、示例解析

3.1 线程切换

当上头的例子中,涉及到了简单栽档次的操作:

  • 亟待在后台执行的耗时操作,对应于subscribe(ObservableEmitter<Integer> e)遭遇之代码。
  • 需要在主线程进行UI创新的操作,对应于DisposableObserver的装有回调,具体的是以onNext被开展速度的更新;在onCompleteonError中展示最终之处理结果。

那,这点儿种类型操作所运行的线程是于哪指定的也,关键是下边就词:

observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(disposableObserver);
  • subscribeOn(Schedulers.io()):指定observablesubscribe措施运行于后台线程。
  • observeOn(AndroidSchedulers.mainThread()):指定observer的回调方法运行在主线程。

及时半独函数刚开的时死有或为瞎,我是这样记的,subscribeOns起,可以知道呢“上游”开头的谐音,也就是是上游实施之线程。

至于这简单只函数,还有少数证:多次调用subscribeOn,会盖第一不良的也罢按;而频繁调用observeOn虽会以最终一蹩脚的啊仍,不过貌似我们且非会见如此干,就不举例子了。

3.2 线程的档次

subscribeOn/observeOn且务求传入一个Schedulers的子类,它就代表了运行线程类型,下面我们来拘禁一下还生安选择:

  • Schedulers.computation():用于计算任务,默认线程数等于处理器的数据。
  • Schedulers.from(Executor executor):使用Executor作为调度器,关于Executor框架可以参考这首文章:大多线程知识梳理(5) –
    线程池四总理曲之 Executor
    框架。
  • Schedulers.io( ):用于IO密集型任务,例如访问网络、数据库操作等,也是咱们最常使用的。
  • Schedulers.newThread( ):为各个一个任务创造一个初的线程。
  • Schedulers.trampoline( ):当其他排队的职责到位后,在脚下线程排队开始实践。
  • Schedulers.single():所有任务并用一个后台线程。

以上是以io.reactivex.schedulers包中,提供的Schedulers,而而我们导入了下的倚重,那么在io.reactivex.android.schedulers生,还有额外的有限个Schedulers可选:

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
  • AndroidSchedulers.mainThread():运行在应用程序的主线程。
  • AndroidSchedulers.from(Looper looper):运行于拖欠looper对应之线程当中。

3.3 使用 CompositeDisposable 对下游进行田间管理

如果Activity比方被灭绝时,我们的后台任务没有尽完毕,那么即使见面促成Activity免克健康回收,而对于各级一个Observer,都见面发生一个Disposable目标用于管理,而RxJava提供了一个CompositeDisposable好像用于管理这些Disposable,我们就待用那用称到该集当中,在ActivityonDestroy道吃,调用它的clear计,就能免内存泄漏的发。

四、小结

这个系列之率先篇稿子,我们介绍了何等运用subscribeOn/observeOn来落实后台执行耗时任务,并通知主线程更新进度。


再也多篇,欢迎访问我的 Android 知识梳理系列:

  • Android
    知识梳理目录:http://www.jianshu.com/p/fd82d18994ce
  • 个人主页:http://lizejun.cn
  • 个体知识总结目录:http://lizejun.cn/categories/
网站地图xml地图