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 線程,而設置圖片則被設定在了主線程。這就意味着,即便加載圖片耗費了幾十甚至幾百毫秒的時間,也不會形成絲毫界面的卡頓。單元測試

相關文章
相關標籤/搜索