圖片來自極客學院
RxJava是當前Android開發(fā)者中越來越普及葛菇,唯一的問題是在學習的初期比較困難甘磨。目前大多數(shù)人都習慣用命令行式編程,但是只要你理解它以后眯停,就會覺得她太棒了~
話不多說济舆,讓我們開始正文,先放上Github上的鏈接:
在正文開始前莺债,我們來說一下RxJava學習中會遇到的一些問題RxJava采用的是響應式編程滋觉,它和傳統(tǒng)的命令行編程有區(qū)別,一些同學一時間無法轉(zhuǎn)變思維齐邦,就會在學習和理解上遇到一些困難本篇文章會針對RxJava的響應式編程和傳統(tǒng)命令行式編程的區(qū)別進行講解椎侠,來幫助初學者更好的理解RxJava的基本概念~
RxJava的概念
1.RxJava的自我介紹:
RxJava 在 GitHub 主頁上的自我介紹是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一個在Java虛擬機上,使用“可觀察的序列”構(gòu)成基于事件的措拇,異步的程序庫)我纪。一句話概括了RxJava。
但是對于初學者來說丐吓,比較難以理解宣羊;簡單點說,它是一個實現(xiàn)異步操作的庫汰蜘。我們先這么理解仇冯。
2.RxJava 的優(yōu)勢:
講到異步操作,我們Android中可以用AsyncTask / Handler族操。苛坚。。來實現(xiàn)色难,為什么還要用RxJava呢泼舱?那么來看看RxJava的優(yōu)勢;
- 簡潔——隨著程序邏輯變得越來越復雜枷莉,它依然能夠保持簡潔
- 高效——快速開發(fā)娇昙,代碼一條從上到下的鏈式調(diào)用,代碼結(jié)構(gòu)清晰
3.觀察者模式
RxJava是以一種拓展的觀察者模式來實現(xiàn)的笤妙,那么我們先來簡單的介紹一下冒掌,觀察者模式:
A對象 (觀察者)監(jiān)聽B對象 (被觀察者)的某種變化噪裕,并瞬間做出反應。
如圖所示股毫,通過 setOnClickListener() 方法設置監(jiān)聽(訂閱)膳音,當用戶點擊時,Button 自動調(diào)用 OnClickListener 的 onClick() 方法铃诬,將點擊事件傳遞給OnClickListener 祭陷。這就是我們點擊事件使用的觀察者模式;
轉(zhuǎn)化一下趣席,如上圖兵志;這就是通用的觀察者模式。當Observable(被觀察者)與Observer(觀察者)達成訂閱關系后宣肚,被觀察者會調(diào)用觀察者的OnEvent()方法想罕,將事件傳遞給觀察者。
響應式-觀察者模式的進階
RxJava使用的就是通用形式的觀察者模式:
- 普通事件 onNext() (相當于 onClick() / onEvent())钉寝;
- 特殊事件:onCompleted() 和 onError()。
如圖所示闸迷,RxJava的基本概念分別為:Observable(被觀察者)嵌纲,Observer(觀察者),22subscribe (訂閱)腥沽、事件逮走; 不同的是,RxJava 把多個事件看做一個隊列今阳,并對每個事件單獨處理师溅;因此,除了普通的事件盾舌,還增加了2個特殊事件墓臭。
onCompleted():當隊列中沒有新的事件產(chǎn)生,也就是所有事件執(zhí)行完畢妖谴,就是調(diào)用onCompleted()方法窿锉,作為完結(jié)的標識;
onError():當事件運行時發(fā)生異常膝舅,會會調(diào)用onError()方法進行異常處理嗡载,并且終止隊列。
注意:在一個隊列中onCompleted() 和 onError()仍稀,只有一個會被調(diào)用洼滚。因為,如果調(diào)用了onCompleted()就說明隊列執(zhí)行完畢技潘,沒有出現(xiàn)異常遥巴,則不會調(diào)用onError()方法千康。相對的,如果隊列異常挪哄,調(diào)用onError()方法的同時會終止隊列吧秕,隊列也就無法完成。
舉個栗子(代碼演示)
接下來迹炼,我們通過代碼砸彬,來看看RxJava編程和傳統(tǒng)命令行編程的區(qū)別和優(yōu)勢:
/**
* 假設:1.我們有一個Listview,用于顯示顯示多張圖片
* 2.現(xiàn)在給出一個目錄數(shù)組斯入,把所有目錄中的jpg圖片都顯示到listview中
* 3.讀取圖片是耗時操作砂碉,需要在后臺運行,listview更新需要在UI線程執(zhí)行
*
* 常規(guī)實現(xiàn)方式:
*/
public void updataImage(final File[] routes, final Context context) {
new Thread() {
@Override
public void run() {
super.run();
for (File route : routes) {
File[] files = route.listFiles();
for (File file : files) {
if (file.getName().endsWith(".jpg")) {
final Bitmap bitmap = getBitmap(file);
((MainActivity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
imageList.add(bitmap);
imageListAdatper.notifyDataSetChanged();
}
});
}
}
}
}
}.start();
}
用RxJava是這樣實現(xiàn)的:
public void updataImage() {
Observable.from(routes)
.flatMap(new Func1<File, Observable>() {
@Override
public Observable call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1<File, Boolean>() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".jpg");
}
})
.map(new Func1<File, Bitmap>() {
@Override
public Bitmap call(File file) {
return getBitmap(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1() {
@Override
public void call(Bitmap bitmap) {
imageList.add(bitmap);
imageListAdatper.notifyDataSetChanged();
}
});
}
這里可能有人會問了刻两,不是說既優(yōu)雅又簡潔嗎增蹭?代碼怎么變多了。我們從整體結(jié)構(gòu)看一下磅摹,你會發(fā)現(xiàn)整個代碼結(jié)構(gòu)是從上到下滋迈,一條鏈條式的調(diào)用,沒有嵌套户誓,這個在邏輯的簡潔性上有非常大的優(yōu)勢饼灿。并且我們的需求越復雜,這種優(yōu)勢越明顯帝美。
比如:我們要再限制顯示圖片的數(shù)量碍彭,那我們只需要把寫好的代碼,添加到相應位置悼潭,就可以對這個功能進行拓展庇忌,所有它的拓展性和可維護性是非常高的。
再比如:我們要維護一個陳年老項目舰褪,如果對于傳統(tǒng)的方式皆疹,我們可能要一層一層代碼的理解,遇到迷之嵌套就很難閱讀占拍。而如果用RxJava墙基,就可以通過一條鏈式的閱讀,非乘⑾玻快速的掌握代碼的邏輯残制。
講到這里,可以了解到為什么說“RxJava非常的好掖疮!”他就好在初茶,可以吧任何復雜的邏輯,簡化成一條線一樣的代碼;方便我們的開發(fā)恼布,維護和閱讀~螺戳!
目前,我們有很多復雜的APP開始采用響應式編程的方式折汞,下面我們來看一下極客學院的一個使用 RxJava 設計的APP 效果圖吧:
如有興趣倔幼,歡迎查看極客學院官網(wǎng),如果你是一位Android 初學者爽待,想要提升技術损同,歡迎訪問下列鏈接。