我們已經知道如何處理緩慢的I/O操作。讓我們看一個與I/O無關的耗時的任務。例如,我們修改loadList()函數并創(chuàng)建一個新的slow函數發(fā)射我們已安裝的app數據。
private Observable<AppInfo> getObservableApps(List<AppInfo> apps) {
return Observable .create(subscriber -> {
for (double i = 0; i < 1000000000; i++) {
double y = i * i;
}
for (AppInfo app : apps) {
subscriber.onNext(app);
}
subscriber.onCompleted();
});
}
正如你看到的,這個函數執(zhí)行了一些毫無意義的計算,只是針對這個例子消耗時間,然后從List<AppInfo>對象中發(fā)射我們的AppInfo數據,現(xiàn)在,我們重排loadList()函數如下:
private void loadList(List<AppInfo> apps) {
mRecyclerView.setVisibility(View.VISIBLE);
getObservableApps(apps)
.subscribe(new Observer<AppInfo>() {
@Override
public void onCompleted() {
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), "Here is the list!", Toast.LENGTH_LONG).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(getActivity(), "Something went wrong!", Toast.LENGTH_SHORT).show();
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onNext(AppInfo appInfo) {
mAddedApps.add(appInfo);
mAdapter.addApplication(mAddedApps.size() - 1, appInfo);
}
});
}
如果我們運行這段代碼,當我們點擊Navigation Drawer菜單項時App將會卡住一會,然后你能看到下圖中半關閉的菜單:
http://wiki.jikexueyuan.com/project/rxjava/images/chapter7_3.png" alt="" />
如果我們不夠走運的話,我們可以看到下圖中經典的ANR信息框:
http://wiki.jikexueyuan.com/project/rxjava/images/chapter7_4.png" alt="" />
可以確定的是,我們將會看到下面在logcat中不愉快的信息:
I/Choreographer Skipped 598 frames! The application may be doing too much work on its main thread.
這條信息比較清楚,Android在告訴我們用戶體驗非常差的原因是我們用不必要的工作量阻塞了UI線程。但是我們已經知道了如何處理它:我們有調度器!我們只須添加幾行代碼到我們的Observable鏈中就能去掉加載慢和Choreographer信息:
getObservableApps(apps)
.onBackpressureBuffer()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<AppInfo>() { [...]
用這幾行代碼,我們將可以快速關掉Navigation Drawer,一個漂亮的進度條,一個工作在獨立的線程緩慢執(zhí)行的計算任務,并在主線程返回結果讓我們更新已安裝的應用列表。