RxJava学习( 二)

1) Scheduler 的 API (一)

在RxJava 中,Scheduler ——调度器,至关于线程控制器,RxJava 经过它来指定每一段代码应该运行在什么样的线程。RxJava 已经内置了几个 Scheduler ,它们已经适合大多数的使用场景:java

  • Schedulers.immediate(): 直接在当前线程运行,至关于不指定线程。这是默认的 Scheduler
  • Schedulers.newThread(): 老是启用新线程,并在新线程执行操做。
  • Schedulers.io(): I/O 操做(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差很少,区别在于 io() 的内部实现是是用一个无数量上限的线程池,能够重用空闲的线程,所以多数状况下 io() 比 newThread() 更有效率。不要把计算工做放在 io() 中,能够避免建立没必要要的线程。
  • Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操做限制性能的操做,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操做放在 computation() 中,不然 I/O 操做的等待时间会浪费 CPU。
  • 另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操做将在 Android 主线程运行。
  • Schedulers.from(executor):使用指定的Executor做为Scheduler;
  • Schedulers.test():用于测试目的,支持单元测试的高级事件;
  • Schedulers.trampoline():在当前线程中的工做放入队列中排队,并依次操做。

 

   有了这几个 Scheduler ,就可使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。数据库

  • subscribeOn(): 指定 subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫作事件产生的线程。
  • observeOn(): 指定 Subscriber 所运行在的线程。或者叫作事件消费的线程。即回调的线程。

二者最主要的差异是影响的范围不一样,observeOn is more limited,可是倒是能够屡次调用,屡次改变不一样的接受者所在的schedule,在调用这个函数以后的observable形成影响。而subscribeon则是一次性的,不管在什么地方调用,老是从改变最原始的observable开始影响整个observable的处理网络

   上代码:ide

Observable.just(1, 2, 3, 4)
    .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
    .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
    .subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer number) {
            Log.d(tag, "number:" + number);
        }
    });

上面这段代码中,因为 subscribeOn(Schedulers.io()) 的指定,被建立的事件的内容 1234 将会在 IO 线程发出;而因为observeOn(AndroidScheculers.mainThread()) 的指定,所以 subscriber 数字的打印将发生在主线程 。事实上,这种在subscribe() 以前写上两句 subscribeOn(Scheduler.io()) 和 observeOn(AndroidSchedulers.mainThread()) 的使用方式很是常见,它适用于多数的 『后台线程取数据,主线程显示』的程序策略。函数

而前面提到的由图片 id 取得图片并显示的例子,若是也加上这两句:性能

int drawableRes = ...; ImageView imageView = ...; Observable.create(new OnSubscribe<Drawable>() { @Override public void call(Subscriber<? super Drawable> subscriber) { Drawable drawable = getTheme().getDrawable(drawableRes)); subscriber.onNext(drawable); subscriber.onCompleted(); } }) .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程 .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程 .subscribe(new Observer<Drawable>() { @Override public void onNext(Drawable drawable) { imageView.setImageDrawable(drawable); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { Toast.makeText(activity, "Error!", Toast.LENGTH_SHORT).show(); } });

那么,加载图片将会发生在 IO 线程,而设置图片则被设定在了主线程。这就意味着,即便加载图片耗费了几十甚至几百毫秒的时间,也不会形成丝毫界面的卡顿。单元测试

相关文章
相关标签/搜索