首先漓帅,異步就是你要獲得一個(gè)操作的結(jié)果锨亏,但是短時(shí)間內(nèi)不能得到,于是你就讓那個(gè)操作等得到結(jié)果的時(shí)候發(fā)個(gè)通知給你忙干,讓你知道已經(jīng)有結(jié)果了器予,這既是異步。
然后這幾天一直在看RxJava捐迫,就是處理Android異步操作的一個(gè)很簡(jiǎn)潔的庫(kù)劣摇。
RXJava
關(guān)于這個(gè)庫(kù),這篇文章講的很仔細(xì) 給Android開(kāi)發(fā)者的RxJava詳解弓乙。
摘了幾個(gè)重要的點(diǎn)出來(lái)末融。
Android 創(chuàng)造的AsyncTask和Handler,其實(shí)都是為了讓異步代碼更加簡(jiǎn)潔暇韧。RxJava 的優(yōu)勢(shì)也是簡(jiǎn)潔勾习,但它的簡(jiǎn)潔的與眾不同之處在于,隨著程序邏輯變得越來(lái)越復(fù)雜懈玻,它依然能夠保持簡(jiǎn)潔巧婶。
代碼例子
Observable.from(folders)
.flatMap(newFunc1>() {
@Override
public Observable call(Filefile) {
return Observable.from(file.listFiles());
}
})
.filter(newFunc1() {
@Override
public Boolean call(Filefile) {
returnfile.getName().endsWith(".png");
}
})
.map(newFunc1() {
@Override
public Bitmap call(Filefile) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(newAction1() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});
1 擴(kuò)展的觀察模式
然后看到這里才想起來(lái)之前原來(lái)是接觸過(guò)RxJava的,但是當(dāng)時(shí)沒(méi)用心理解涂乌。
觀察模式就是有一個(gè)Oberserver -- 觀察者和一個(gè)Observable -- 被觀察者艺栈,在這里,觀察者不用時(shí)時(shí)刻刻去檢查被觀察者的狀態(tài)湾盒,因?yàn)橹灰挥^察者結(jié)束了它的工作湿右,產(chǎn)生了觀察者需要的結(jié)果后,它會(huì)提醒觀察者罚勾, 方式稱(chēng)為“Subscribe”訂閱或者 “Register”注冊(cè)毅人。所以在這里吭狡,和往常的羅邏輯不通,這里是observable.subscribe(oberserver),看起來(lái)像是被觀察者訂閱了觀察者丈莺。這一模式和button的onclickLinsterner很相似划煮,按鈕被點(diǎn)擊,這個(gè)監(jiān)聽(tīng)器就會(huì)收到信號(hào)缔俄。
2 線程控制
實(shí)現(xiàn)異步至關(guān)重要的概念弛秋。
在不指定線程的情況下, RxJava 遵循的是線程不變的原則俐载,即:在哪個(gè)線程調(diào)用 subscribe()
蟹略,就在哪個(gè)線程生產(chǎn)事件;在哪個(gè)線程生產(chǎn)事件瞎疼,就在哪個(gè)線程消費(fèi)事件。如果需要切換線程壁畸,就需要用到 Scheduler
(調(diào)度器)贼急。也可以多次切換
- Schedulers.immediate(): 直接在當(dāng)前線程運(yùn)行,相當(dāng)于不指定線程捏萍。這是默認(rèn)的 Scheduler太抓。
- Schedulers.newThread(): 總是啟用新線程,并在新線程執(zhí)行操作令杈。
- Schedulers.io(): I/O 操作(讀寫(xiě)文件走敌、讀寫(xiě)數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)信息交互等)所使用的 Scheduler逗噩。行為模式和 newThread() 差不多掉丽,區(qū)別在于 io() 的內(nèi)部實(shí)現(xiàn)是是用一個(gè)無(wú)數(shù)量上限的線程池,可以重用空閑的線程异雁,因此多數(shù)情況下 io() 比 newThread() 更有效率捶障。不要把計(jì)算工作放在 io() 中,可以避免創(chuàng)建不必要的線程纲刀。
- Schedulers.computation(): 計(jì)算所使用的 Scheduler项炼。這個(gè)計(jì)算指的是 CPU 密集型計(jì)算,即不會(huì)被 I/O 等操作限制性能的操作示绊,例如圖形的計(jì)算锭部。這個(gè) Scheduler 使用的固定的線程池,大小為 CPU 核數(shù)面褐。不要把 I/O 操作放在 computation() 中拌禾,否則 I/O 操作的等待時(shí)間會(huì)浪費(fèi) CPU。
- 另外展哭, Android 還有一個(gè)專(zhuān)用的 AndroidSchedulers.mainThread()蹋砚,它指定的操作將在 Android 主線程運(yùn)行扼菠。
然后用subscribeOn()和oberserveOn()來(lái)調(diào)用以上的Scheduler
。
subscribeOn(): 指定 subscribe() 所發(fā)生的線程坝咐,即 Observable.OnSubscribe 被激活時(shí)所處的線程循榆。或者叫做事件產(chǎn)生的線程墨坚。
- observeOn(): 指定 Subscriber 所運(yùn)行在的線程秧饮。或者叫做事件消費(fèi)的線程 泽篮。
- suscribeOn(): 指定subscribe()發(fā)生的進(jìn)程盗尸,即observable.OnSubscribe()被激活時(shí)所處的進(jìn)程,或者叫做事件產(chǎn)生的進(jìn)程帽撑。
例子:
3 變換
變換指的是將時(shí)間序列中的對(duì)象或者整個(gè)序列進(jìn)行加工處理泼各,轉(zhuǎn)換成不同的事件或者事件序列。
API
+ map()
+ flatMap()
+ compose()