網絡請求
-
基本操作
RxJava 和 Retrofit 結合使用最基本的格式:用 subscribeOn() 和 observeOn() 來控制線程,并通過 subscribe() 來觸發網絡請求的開始。代碼大致形式:
api.getData().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
-
轉換Map
有些服務端的接口設計,會在返回的數據外層包裹一些額外信息,這些信息對于調試很有用,但本地顯示是用不到的。使用 map() 可以把外層的格式剝掉,只留下本地會用到的核心格式。代碼大致形式:
api.getData().map(response -> response.data).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
當然,map() 也可以用于基于其他各種需求的格式轉換。
-
壓合zip
有的時候,app 中會需要同時訪問不同接口,然后將結果糅合后轉為統一的格式后輸出(例如將第三方廣告 API 的廣告夾雜進自家平臺返回的數據 List 中)。這種并行的異步處理比較麻煩,不過用了 zip() 之后就會簡單得多。代碼大致形式:
Observable.zip(api.getData(),adApi.getAds(), zipFunc()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
-
連續嵌套請求flatMap
出于安全性、性能等方面的考慮,多數服務器會有一些接口需要傳入 token 才能正確返回結果,而 token 是需要從另一個接口獲取的,這就需要使用兩步連續的請求才能獲取數據(①token -> ②目標數據)。使用 flatMap() 可以用較為清晰的代碼實現這種連續請求,避免 Callback 嵌套的結構。代碼大致形式:
api.getToken().flatMap(token -> api.getData(token)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
-
錯誤重試retryWhen
有的 token 并非一次性的,而是可以多次使用,直到它超時或被銷毀(多數 token 都是這樣的)。這樣的 token 處理起來比較麻煩:需要把它保存起來,并且在發現它失效的時候要能夠自動重新獲取新的 token 并繼續訪問之前由于 token 失效而失敗的請求。如果項目中有多處的接口請求都需要這樣的自動修復機制,使用傳統的 Callback 形式需要寫出非常復雜的代碼。而使用 RxJava ,可以用 retryWhen() 來輕松地處理這樣的問題。
@Override
public Observable<?> apply(@NonNull Observable<? extends Throwable> attempts) throws Exception {
return attempts
.flatMap(new Function<Throwable, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {
if (++retryCount <= maxRetries) {
// When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
Log.i(TAG, "get error, it will try after " + retryDelayMillis
+ " millisecond, retry count " + retryCount);
return Observable.timer(retryDelayMillis,
TimeUnit.MILLISECONDS);
}
// Max retries hit. Just pass the error along.
return Observable.error(throwable);
}
});
}