1. 程式人生 > >RxJava 執行緒切換

RxJava 執行緒切換

RxJava中的執行緒切換

一般來說我們在使用網路請求資料後需要使用View來顯示,網路請求當然是在子執行緒中執行,當獲取到資料後就需要切換到UI執行緒來顯示,否則會報錯,RxJava中已經幫我們處理好了執行緒切換的問題。

Observable類兩個介面


@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> subscribeOn(Scheduler scheduler) {
    ObjectHelper.requireNonNull(scheduler, "scheduler is null"
); return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler)); } @SchedulerSupport(SchedulerSupport.CUSTOM) public final Observable<T> observeOn(Scheduler scheduler) { return observeOn(scheduler, false, bufferSize()); }

上面兩個介面是用來做什麼用的呢?

Observable<T> subscribeOn(Scheduler scheduler)

註釋直接翻譯:在指定的Scheduler上非同步訂閱Observers到此ObservableSource

聽起來不太好理解,應該這樣說:在指定的排程執行緒上給可觀察源非同步的訂閱觀察者

Observable<T> observeOn(Scheduler scheduler)

註釋直接翻譯:修改ObservableSource以在指定的Scheduler上執行其發射和通知

也不太好理解,可以這樣說:修改被觀察源到指定的排程執行緒上去執行發射或通知(也就是說在另一個執行緒上去執行某些方法)

看了上面解釋可能還是一頭霧水,現在結合世界場景來理解,看下面示例程式碼


請求介面定義
public
interface NetService { @GET("?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json") Observable<WeatherBeans> requestWeatherBeansRX(); } 介面使用 private void doGetWithRx() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://api.k780.com") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); NetService netService = retrofit.create(NetService.class); Observable<WeatherBeans> observable = netService.requestWeatherBeansRX(); observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<WeatherBeans>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "onSubscribe run"); } @Override public void onNext(WeatherBeans beans) { StringBuilder sb = new StringBuilder(); if (beans != null) { for (WeatherBeans.ResultBean bean : beans.getResult()) { Log.d(TAG, "cityName:" + bean.getCitynm()); sb.append(bean.getCitynm()).append("、"); } resultView.setText(sb.toString()); } else { Log.d(TAG, "OnNext beans is null"); } } @Override public void onError(Throwable e) { Log.d(TAG, "OnError run"); } @Override public void onComplete() { Log.d(TAG, "onComplete run"); } }); }

從上面的示例程式碼我們看到在網路請求的鏈式呼叫。

observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())...

先看subscribeOn(Schedulers.io())

Schedulers.io()的註釋是:建立並返回用於IO繫結工作的Scheduler

那麼subscribeOn也就是在io執行執行緒訂閱,也就是說網路請求io操作在io執行緒

再看observeOn(AndroidSchedulers.mainThread())

AndroidSchedulers.mainThread():一個Scheduler,它在Android主執行緒上執行操作

這兩個介面的作用是如下:

subscribeOn(Schedulers.io())是指定observable的subscribeOn() 方法在後臺執行緒執行。

observeOn(AndroidSchedulers.mainThread())是指定 observer 的回撥方法在主執行緒執行。

實驗1

註釋subscribeOn(Schedulers.io())

結果輸出:

09-27 14:48:51.520 2879-2879/hq.demo.net D/NewOkHttpFragment: onSubscribe run 09-27 14:48:51.556 2879-2879/hq.demo.net D/NewOkHttpFragment: onError run

可以看到回調了onError,說明請求錯誤了

實驗2

註釋掉observeOn(AndroidSchedulers.mainThread())

結果輸出:

09-27 14:54:49.481 4059-4059/hq.demo.net D/NewOkHttpFragment: onSubscribe run 09-27 14:54:49.735 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.735 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:54:49.738 4059-4099/hq.demo.net D/NewOkHttpFragment: OnError run

上面結果說明網路請求結果成功,但是resultView.setText(sb.toString());出錯,

實驗3

去掉所有註釋

結果輸出:

09-27 14:58:51.008 4349-4349/hq.demo.net D/NewOkHttpFragment: onSubscribe run 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京 09-27 14:58:51.232 4349-4349/hq.demo.net D/NewOkHttpFragment: onComplete run

總結:

RxJava在資料請求展示中的執行緒切換是通過下面介面處理的,

1、subscribeOn(Schedulers.io())   指定observable的 subscribeOn() 方法在後臺執行緒執行。

2、observeOn(AndroidSchedulers.mainThread())  指定 observer 的回撥方法在主執行緒執行。