進擊的 RxJava
上篇簡單說了 Retrofit 配上 RxJava 一起用,ofollow,noindex">https://www.jianshu.com/p/0c618a7a797e ,我們接著再來說說裝配上 RxJava 之後到底能解決哪些實際問題呢?
程式碼簡潔
藉助 retorfit 加 rxjava,我們就不需要再做其他多餘的封裝或修改。網路請求寫起來就會簡單許多,而且結構也清晰。被觀察者就是請求的發起,觀察者就是請求的回撥。
操作符的作用
rxjava 的優勢就在於其操作符的使用,我理解的「操作符」就是 rxjava 為我們提供了一系列方法,可以運用在觀察者模式中的「被觀察者」「觀察者」或「訂閱過程」之間來控制。實際專案中我遇到過以下幾種常見情況,可以用操作符來處理。
1.請求結果需要做資料處理之後,再給頁面展示。 「map」操作符,這個操作符就是在請求回來之後直接對資料做處理之後再返回給觀察者。
SampleObservable observable = SampleRetrofitManager.getInstance().service.getService(); observable.map(new Function<ResponseBean, Object>() { @Override public Object apply(ResponseBean responseBean) throws Exception { //這裡可以處理返回資料,處理完後返回想要的資料,最後可以在 onNext 做後續處理 return null; } }).subscribe(new Observer<Object>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Object o) { } @Override public void onError(Throwable e) { } @Override public void onComplete() { } });
2.請求結果是做為下一個請求的請求入參。「flatMap」操作符,這個操作符是在遇到串聯請求時使用的,當第一個請求返回結果之後,再拿著結果去請求下一個介面。
SampleObservable observable = SampleRetrofitManager.getInstance().service.getFirstService(); observable.flatMap(new Function<ResponseBean, Observable<SampleResp>>() { @Override public Observable<SampleResp> apply(ResponseBean responseBean) throws Exception { //這裡接收到第一個請求的返回結果之後,再用來發起第二個請求,也可在發起請求前先做一些資料處理 return SampleRetrofitManager.getInstance().service.getSecondService(responseBean); } }).subscribe(new Observer<Object>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Object o) { } @Override public void onError(Throwable e) { } @Override public void onComplete() { } });
3.多個請求同時發起,頁面的展示需要多個請求結果共同組織。「zip」操作符,當一個頁面的資料來自多個請求時,但又是同一個展示頁面時,這個操作符就比較合適。它可以讓多個請求同時發起,並在各個請求都返回後,統一處理再返回結果給頁面展示。
Observable.zip(observable1, observable2, new Bifunction<Response1, Response2, TotalResponse>(){ @Override public TotalResponse apply(Response1 r1, Response2 r2) throws Exception { return null; } }).subscribe(new Observer<TotalResponse>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(TotalResponse response) { } @Override public void onError(Throwable e) { } @Override public void onComplete() { } });
請求 observable1, observable2 的返回分別是 r1, r2 而頁面需要的是 TotalResponse,通過 zip 操作符處理後,請求就變得簡單很多,最後只要關心 response 來進行頁面展示就好了。
另外關於執行緒切換,一開始用的時候覺得耗時任務用 Schedulers.newThread() 就夠了,但是對比了 Schedulers.io() 之後發現大家更傾向後者(原因在於後者會有執行緒池來管理執行緒,雖說從字面意思上看是專門用來處理 io 操作的執行緒,但用來做一般耗時任務也是可以的),所以我以後也會採用 io() 來代替 newThread()。
目前專案中暫時遇到的情況是上面這些,新的情況後續還會總結。