相信看完前兩篇文章网棍,相信大家對(duì)RxJava的用例已經(jīng)有個(gè)比較清晰的認(rèn)識(shí)了。今天我們來(lái)看看RxJava的一個(gè)extension-RxAndroid妇智。
1.RxAndroid主線程調(diào)度器
說(shuō)到RxAndroid俘陷,大部分已經(jīng)接觸過(guò)RxJava的同學(xué)都可能看過(guò)這個(gè)類(lèi)似的代碼
沒(méi)錯(cuò)罗捎,就是這個(gè)AndroidSchedulers.mainThread()線程調(diào)度器。在經(jīng)典的安卓后臺(tái)處理拉盾,主線程接收結(jié)果場(chǎng)景中經(jīng)常被使用桨菜。
不過(guò)說(shuō)實(shí)話,我個(gè)人在參與公司的app編寫(xiě)的過(guò)程中捉偏,RxAndroid部分最常用到的也就是這個(gè)調(diào)度器而已了倒得。。夭禽。
RxAndroid當(dāng)然不止這么點(diǎn)用處霞掺,我們接下來(lái)探索一下其他RxAndroid的用例。
首先我們打開(kāi)RxAndroid的Wiki Page讹躯,可以看到有一大堆extension呢菩彬!
今天我們就以其中一個(gè)最常用的RxBinding為例。
RxBinding是用來(lái)干哈的潮梯?我個(gè)人的理解是它是一個(gè)把a(bǔ)ndroid中各種view的listener轉(zhuǎn)換成Rx里面的Observable的一個(gè)庫(kù)骗灶。一個(gè)最簡(jiǎn)單的例子:替換掉view的onClicklistener:
哈哈!成功啦!我們邁向了RxAndroid的第一步。溉愁。。纳像。。。。我露出了尷尬的笑容
乍一看绕娘,這有啥意義嗎?從原來(lái)的setOnclickListener()到現(xiàn)在這個(gè)bingding栽连,并沒(méi)有看到有什么優(yōu)勢(shì)啊业舍。
年輕人別上火,咱們來(lái)仔細(xì)分析一下升酣。既然我們成功的把一個(gè)view的click事件轉(zhuǎn)換成了Observable舷暮,那么我們就可以玩很多花活了,所有在Observable上可以應(yīng)用的操作符我們現(xiàn)在都可以應(yīng)用到android的view上拉噩茄!
2.實(shí)現(xiàn)雙擊響應(yīng)下面!
比如說(shuō),假如我們想實(shí)現(xiàn)一個(gè)按鈕雙擊的響應(yīng)事件绩聘,在android里面應(yīng)該怎么實(shí)現(xiàn)呢沥割?先貼出代碼,我們?cè)僮屑?xì)分析分析凿菩。
可以看到我們?cè)谶@個(gè)例子里面,把原始的textview的observable通過(guò)buffer()操作符改裝了一下衅谷。讓我們看看buffer是干嘛的椒拗。
周期性的把一個(gè)原始的Observable要發(fā)射的元素集中在多個(gè)集合里面,然后把這些集合一個(gè)個(gè)發(fā)射出去(而不是原始的元素)获黔。
這和我們雙擊事件有什么聯(lián)系呢蚀苛?讓我們來(lái)想想,雙擊鼠標(biāo)玷氏,雙擊button堵未,本質(zhì)是什么?本質(zhì)就是在一個(gè)比較短的時(shí)間段內(nèi)盏触,點(diǎn)擊了目標(biāo)兩次渗蟹,不能是一次,也不能是三次赞辩。這個(gè)比較短的時(shí)間是多少雌芽,一秒??jī)擅胧坎恢匾炫隆R驗(yàn)檫@是由開(kāi)發(fā)者自己決定的。那么使用buffer操作符的話召庞,我們可以不斷的監(jiān)聽(tīng)我們的click事件的同時(shí)岛心,把他們按照兩個(gè)兩個(gè)的組合起來(lái),那么每次我們就只處理這個(gè)兩個(gè)點(diǎn)擊事件的集合篮灼,而不是單個(gè)點(diǎn)擊事件忘古。
看看buffer的使用,四個(gè)參數(shù):
參數(shù)1:時(shí)間段的長(zhǎng)短
參數(shù)2:時(shí)間段的單位
參數(shù)3:我們選擇發(fā)射集合的大小诅诱,這里因?yàn)槲覀冃枰氖请p擊事件髓堪,所以這個(gè)參數(shù)3我們會(huì)選擇2.
參數(shù)4:線程調(diào)度器,這里我們?cè)诎沧康闹骶€程監(jiān)聽(tīng)事件的發(fā)生。
至于在subscribe里面干旁,為什么我們還需要判斷一下list的大惺徽印?
因?yàn)橐坏﹕ubscribe争群,我們的Observable會(huì)每隔一段時(shí)間(就是你定義的時(shí)間),發(fā)射一個(gè)集合回怜,這個(gè)集合可能是空的,或者只含有一個(gè)元素(比如說(shuō)在500ms里面你壓根沒(méi)點(diǎn)擊换薄,或者只點(diǎn)擊了一次)玉雾。
3.優(yōu)雅的響應(yīng)改變
第三部分的例子來(lái)源于這個(gè)家伙寫(xiě)的一個(gè)blog文章,假設(shè)你有一個(gè)textview,和一個(gè)edittext轻要,每次edittext改變的時(shí)候你都想把edittext的內(nèi)容轉(zhuǎn)換順序复旬,并且顯示到textview上面。使用rxbinding將edittext的響應(yīng)事件更優(yōu)雅的來(lái)處理把冲泥!
4.上述例子的一些缺點(diǎn)驹碍。
稍微陳述一下上述例子的缺點(diǎn)吧。
首先例子1的雙擊事件柏蘑,每次在subscribe之后幸冻,RxJava都會(huì)開(kāi)啟一個(gè)timer,定時(shí)的去獲取事件咳焚。這樣具體對(duì)手機(jī)power的消耗是否會(huì)增加太多洽损,我不太確定。但是肯定是比不用timer要多的
例子2中革半,RxTextView的textChanges()方法之響應(yīng)了EditText的onTextChanged()方法碑定。beforeTextChanged 和 afterTextChanged是沒(méi)有響應(yīng)的。大家有興趣可以看看它的實(shí)現(xiàn)又官,就是把textwatcher的方法重寫(xiě)延刘,每次onTextChanged的時(shí)候就發(fā)射一個(gè)事件。
5.最后關(guān)于流的思考六敬。
其實(shí)寫(xiě)了這些例子并不是為了要大家就按照我寫(xiě)的去做碘赖,具體項(xiàng)目的需求不一樣,寫(xiě)法肯定也不一樣外构。我寫(xiě)這些的目的是為了讓大家可以明白普泡,RxAndroid的這些extension,例如rxbinding的存在意義是什么审编。
他們的意義是撼班,把平常我們?cè)诎沧块_(kāi)發(fā)接觸過(guò)程中的一些組件,以RxJava概念里面的流(Stream)呈現(xiàn)出來(lái)垒酬。就像大部分文章里面提到的砰嘁,在Rx的世界里面件炉,everything is stream“妫或者更詳細(xì)的說(shuō)斟冕,everything is event stream。這也呼應(yīng)了Rx的event-driven的本質(zhì)板祝。
這里的stream宫静,流,和我們?cè)趈ava api里面的stream理解稍微不太一樣券时。Rx里面的流,可以理解為一個(gè)事件的流伏伯,這個(gè)流可以是從一個(gè)List里面提取的橘洞,擁有有限個(gè)元素的流,或者是一個(gè)網(wǎng)絡(luò)請(qǐng)求的流说搅,有限個(gè)元素炸枣,但是你不知道它從一個(gè)元素的發(fā)射到下一個(gè)元素的發(fā)射需要多久(網(wǎng)絡(luò)請(qǐng)求時(shí)間),又或者是像點(diǎn)擊事件這種弄唧,擁有無(wú)限個(gè)元素适肠,發(fā)射間隔完全取決于用戶。
這就是為什么RxJava在他們的wiki page里面候引,每一個(gè)operator都配上了一個(gè)侯养,一條直線,一個(gè)箭頭澄干,直線上有若干元素的圖了逛揩。
時(shí)間朝著箭頭的方向走麸俘,事件也有序的一個(gè)個(gè)發(fā)射辩稽。
變成流之后,我們就可以用各種操作符把原始的流从媚,改變成我們需要的流了逞泄,每一次我們使用一個(gè)操作符比如filter, map等拜效,我們其實(shí)已經(jīng)把原始的流改變成一個(gè)新的流了喷众。
這是我個(gè)人關(guān)于Rx里面的流的一點(diǎn)思考,希望對(duì)大家有幫助拂檩。
最后
最近工作有點(diǎn)忙侮腹,關(guān)于RxJava的文章會(huì)在兩周之后更新。我會(huì)著重講解一下RxJava的一些源代碼稻励。