RxJava是非常熱門的函式響應式程式設計庫,在Android開發中已經非常流行了,剛開始上手會有點難,但只要理解了它,就再也回不去了;不使用RxJava寫非同步請求的話,就感覺各種不爽。
本文不準備講RxJava的基礎知識,如果你對RxJava不熟悉,這裡有篇不錯的教程可以參考《給 Android 開發者的 RxJava 詳解》。
下面我們開始介紹RxJava最適合使用的四種場景,程式碼示例基於RxJava1
場景一: 單請求非同步處理
由於在Android UI執行緒中不能做一些耗時操作,比如網路請求,大檔案儲存等,所以在開發中經常會碰到非同步處理的情況,我們最典型的使用場景是RxJava+Retrofit處理網路請求
MyService myService = retrofit.create(MyService.class);
myService.getSomething()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateUI, this::showError);複製程式碼
為了使程式碼看起來簡潔點,這邊還使用了lambda表示式,updateUI
和showError
需要在當前類中實現,比如:
public void updateUI(Data data){
//TODO something
}
public void showError(throwable t){
//show error msg
}複製程式碼
場景二: 多非同步請求連續呼叫
這種場景其實也很常見,我們做使用者頭像編輯的使用,一般就會有三個請求需要連續呼叫:
- 請求頭像上傳的地址
- 上傳頭像
- 更新使用者資訊
在平時的程式碼裡,我們需要一步步callback巢狀下來,程式碼冗長太難看,而且不好維護,使用RxJava鏈式呼叫處理程式碼邏輯就會非常清晰
MyService myService = retrofit.create(MyService.class);
myService.getUploadUrl()
.flatMap(this::uploadImageTask)
.flatMap(this::updateUserInfo)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateUI, this::showError);複製程式碼
先獲取請求,再上傳頭像,最後更新使用者資訊,後面的任務依賴上一步的處理結果,依次執行。
場景三: 多非同步請求合併處理
有時候在專案中,我們會碰到組合多個請求的結果後,再更新UI的情況,比如我們專案中就有一個從多個請求地址獲取通知資料,然後在APP上再按時間順序組合後展示的需求,這時候我們就可以用RxJava的zip函式來處理了
MyService myService = retrofit.create(MyService.class);
Observable o1 = myService.getNotification1();
Observable o2 = myService.getNotification2();
Observable.zip(o1,o2, this::combiNotification)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateUI, this::showError);
public List<Notification> combiNotification(List<Notification> n1, List<Notification> n2){
//TODO 合併通知列表
}複製程式碼
zip函式會等待兩個請求都完成後,呼叫我們的合併方法combiNotification,等合併處理後再回撥subscribe中的方法。
場景四: 定時輪詢
RxJava還特別適合對定時輪詢任務的處理, 一種典型的例子就是APP提交了一個任務給後臺非同步處理,假設後臺處理需要1-2分鐘左右,我們需要定時到後臺查詢進度,並更新到UI上, 傳統的做法是用Handler的postDelay方法,用RxJava實現的話就會非常簡潔
Subscription subscription = Observable.interval(2, TimeUnit.SECONDS)
.map(this::getProgress)
.takeUntil(progress -> progress != 100)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
//TODO finished
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(int progress) {
//TODO update progress
}
});複製程式碼
我們以定時2秒查詢一次,直到進度progress=100為止,自動終止輪詢。
以上各種RxJava方法都是非同步耗時呼叫,考慮到Activity的退出時請求還沒有完成,我們需要在Activity的OnDestroy方法中取消RxJava呼叫
subscription.unsubscribe();複製程式碼
本文作者: 陽春麵
本文連結: appkfz.com/2017/09/01/…
版權宣告: 本部落格所有文章除特別宣告外,均採用 CC BY-NC-SA 3.0 許可協議。轉載請註明出處!
掃一掃下方二維碼,關注我的微信公眾號(APP開發進階),第一時間獲得Android開發進階文章