我們已經(jīng)知道如何處理緩慢的I/O操作。讓我們看一個(gè)與I/O無(wú)關(guān)的耗時(shí)的任務(wù)。例如,我們修改loadList()函數(shù)并創(chuàng)建一個(gè)新的slow函數(shù)發(fā)射我們已安裝的app數(shù)據(jù)。
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();
});
}
正如你看到的,這個(gè)函數(shù)執(zhí)行了一些毫無(wú)意義的計(jì)算,只是針對(duì)這個(gè)例子消耗時(shí)間,然后從List<AppInfo>對(duì)象中發(fā)射我們的AppInfo數(shù)據(jù),現(xiàn)在,我們重排loadList()函數(shù)如下:
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);
}
});
}
如果我們運(yùn)行這段代碼,當(dāng)我們點(diǎn)擊Navigation Drawer菜單項(xiàng)時(shí)App將會(huì)卡住一會(huì),然后你能看到下圖中半關(guān)閉的菜單:
http://wiki.jikexueyuan.com/project/rxjava/images/chapter7_3.png" alt="" />
如果我們不夠走運(yùn)的話,我們可以看到下圖中經(jīng)典的ANR信息框:
http://wiki.jikexueyuan.com/project/rxjava/images/chapter7_4.png" alt="" />
可以確定的是,我們將會(huì)看到下面在logcat中不愉快的信息:
I/Choreographer Skipped 598 frames! The application may be doing too much work on its main thread.
這條信息比較清楚,Android在告訴我們用戶體驗(yàn)非常差的原因是我們用不必要的工作量阻塞了UI線程。但是我們已經(jīng)知道了如何處理它:我們有調(diào)度器!我們只須添加幾行代碼到我們的Observable鏈中就能去掉加載慢和Choreographer信息:
getObservableApps(apps)
.onBackpressureBuffer()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<AppInfo>() { [...]
用這幾行代碼,我們將可以快速關(guān)掉Navigation Drawer,一個(gè)漂亮的進(jìn)度條,一個(gè)工作在獨(dú)立的線程緩慢執(zhí)行的計(jì)算任務(wù),并在主線程返回結(jié)果讓我們更新已安裝的應(yīng)用列表。