[轉(zhuǎn)]RxJava系列1(簡(jiǎn)介)
前言
提升開發(fā)效率启具,降低維護(hù)成本一直是開發(fā)團(tuán)隊(duì)永恒不變的宗旨二拐。近一年來國內(nèi)的技術(shù)圈子中越來越多的開始提及Rx檩咱,經(jīng)過一段時(shí)間的學(xué)習(xí)和探索之后我也深深的感受到了RxJava的魅力分歇。它能幫助我們簡(jiǎn)化代碼邏輯电谣,提升代碼可讀性盯漂。這對(duì)于開發(fā)效率的提升蛔钙、后期維護(hù)成本的降低幫助都是巨大的储矩。個(gè)人預(yù)測(cè)RxJava一定是2016年的一個(gè)大趨勢(shì)感耙,所以也有打算將它引入到公司現(xiàn)有的項(xiàng)目中來,寫這一系列的文章主要也是為了團(tuán)隊(duì)內(nèi)部做技術(shù)分享持隧。
由于我本人是個(gè)Android程序猿即硼,因此這一系列文章中的場(chǎng)景都是基于Android平臺(tái)的。如果你是個(gè)Java Web工程師或者是其它方向的那也沒關(guān)系屡拨,我會(huì)盡量用通俗的語言將問題描述清楚只酥。
響應(yīng)式編程
在介紹RxJava前,我們先聊聊響應(yīng)式編程呀狼。那么什么是響應(yīng)式編程呢裂允?響應(yīng)式編程是一種基于異步數(shù)據(jù)流概念的編程模式。數(shù)據(jù)流就像一條河:它可以被觀測(cè)哥艇,被過濾绝编,被操作,或者為新的消費(fèi)者與另外一條流合并為一條新的流。
響應(yīng)式編程的一個(gè)關(guān)鍵概念是事件十饥。事件可以被等待窟勃,可以觸發(fā)過程,也可以觸發(fā)其它事件逗堵。事件是唯一的以合適的方式將我們的現(xiàn)實(shí)世界映射到我們的軟件中:如果屋里太熱了我們就打開一扇窗戶秉氧。同樣的,當(dāng)我們的天氣app從服務(wù)端獲取到新的天氣數(shù)據(jù)后蜒秤,我們需要更新app上展示天氣信息的UI谬运;汽車上的車道偏移系統(tǒng)探測(cè)到車輛偏移了正常路線就會(huì)提醒駕駛者糾正,就是是響應(yīng)事件垦藏。
今天梆暖,響應(yīng)式編程最通用的一個(gè)場(chǎng)景是UI:我們的移動(dòng)App必須做出對(duì)網(wǎng)絡(luò)調(diào)用、用戶觸摸輸入和系統(tǒng)彈框的響應(yīng)掂骏。在這個(gè)世界上轰驳,軟件之所以是事件驅(qū)動(dòng)并響應(yīng)的是因?yàn)楝F(xiàn)實(shí)生活也是如此。
本章節(jié)中部分概念摘自《RxJava Essentials》一書
RxJava的來歷
Rx是微軟.Net的一個(gè)響應(yīng)式擴(kuò)展弟灼,Rx借助可觀測(cè)的序列提供一種簡(jiǎn)單的方式來創(chuàng)建異步的级解,基于事件驅(qū)動(dòng)的程序。2012年Netflix為了應(yīng)對(duì)不斷增長的業(yè)務(wù)需求開始將.NET Rx遷移到JVM上面田绑。并于13年二月份正式向外展示了RxJava勤哗。
從語義的角度來看,RxJava就是.NET Rx掩驱。從語法的角度來看芒划,Netflix考慮到了對(duì)應(yīng)每個(gè)Rx方法,保留了Java代碼規(guī)范和基本的模式。
什么是RxJava
那么到底什么是RxJava呢欧穴?我對(duì)它的定義是:RxJava本質(zhì)上是一個(gè)異步操作庫民逼,是一個(gè)能讓你用極其簡(jiǎn)潔的邏輯去處理繁瑣復(fù)雜任務(wù)的異步事件庫。
RxJava好在哪
Android平臺(tái)上為已經(jīng)開發(fā)者提供了AsyncTask,Handler等用來做異步操作的類庫涮帘,那我們?yōu)槭裁催€要選擇RxJava呢拼苍?答案是簡(jiǎn)潔!RxJava可以用非常簡(jiǎn)潔的代碼邏輯來解決復(fù)雜問題调缨;而且即使業(yè)務(wù)邏輯的越來越復(fù)雜疮鲫,它依然能夠保持簡(jiǎn)潔!再配合上Lambda用簡(jiǎn)單的幾行代碼分分鐘就解決你負(fù)責(zé)的業(yè)務(wù)問題弦叶。簡(jiǎn)直逼格爆表俊犯,拿它裝逼那是極好的!
多說無益湾蔓,上代碼瘫析!
假設(shè)我們安居客用戶App上有個(gè)需求,需要從服務(wù)端拉取上海浦東新區(qū)塘橋板塊的所有小區(qū)Community[] communities,每個(gè)小區(qū)下包含多套房源List<House> houses贬循;我們需要把塘橋板塊的所有總價(jià)大于500W的房源都展示在App的房源列表頁咸包。用于從服務(wù)端拉取communities需要發(fā)起網(wǎng)絡(luò)請(qǐng)求,比較耗時(shí)杖虾,因此需要在后臺(tái)運(yùn)行烂瘫。而這些房源信息需要展示到App的頁面上,因此需要在UI線程上執(zhí)行奇适。(此例子思路來源于扔物線的給Android開發(fā)者的RxJava詳解一文)
new Thread() {
@Override
public void run() {
super.run();
//從服務(wù)端獲取小區(qū)列表
List<Community> communities = getCommunitiesFromServer();
for (Community community : communities) {
List<House> houses = community.houses;
for (House house : houses) {
if (house.price >= 5000000) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//將房子的信息添加到屏幕上
addHouseInformationToScreen(house);
}
});
}
}
}
}
}.start();
使用RxJava的寫法是這樣的:
Observable.from(getCommunitiesFromServer())
.flatMap(new Func1<Community, Observable<House>>() {
@Override
public Observable<House> call(Community community) {
return Observable.from(community.houses);
}
}).filter(new Func1<House, Boolean>() {
@Override
public Boolean call(House house) {
return house.price>=5000000;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<House>() {
@Override
public void call(House house) {
//將房子的信息添加到屏幕上
addHouseInformationToScreen(house);
}
});
從上面這段代碼我們可以看到:雖然代碼量看起來變復(fù)雜了坟比,但是RxJava的實(shí)現(xiàn)是一條鏈?zhǔn)秸{(diào)用,沒有任何的嵌套嚷往;整個(gè)實(shí)現(xiàn)邏輯看起來異常簡(jiǎn)潔清晰葛账,這對(duì)我們的編程實(shí)現(xiàn)和后期維護(hù)是有巨大幫助的。特別是對(duì)于那些回調(diào)嵌套的場(chǎng)景皮仁。配合Lambda表達(dá)式還可以簡(jiǎn)化成這樣:
Observable.from(getCommunitiesFromServer())
.flatMap(community -> Observable.from(community.houses))
.filter(house -> house.price>=5000000).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::addHouseInformationToScreen);
簡(jiǎn)潔籍琳!有美感!這才是一個(gè)有情懷的程序員應(yīng)該寫出來的代碼贷祈。
看完這篇文章大家應(yīng)該能夠理解RxJava為什么會(huì)越來越火了趋急。它能極大的提高我們的開發(fā)效率和代碼的可讀性!當(dāng)然了RxJava的學(xué)習(xí)曲線也是比較陡的势誊,在后面的文章我會(huì)對(duì)主要的知識(shí)點(diǎn)做詳細(xì)的介紹呜达,敬請(qǐng)關(guān)注!