【Android】RxJava的使用(一)基本用法

前言

最近經(jīng)诚剿看到RxJava這個(gè)字眼惰说,也看到很多人在博客中推薦使用RxJava。好奇的我怎么能錯(cuò)過(guò)缘回,于是Google了一下吆视,說(shuō)RxJava好用的和說(shuō)RxJava難用的都有,于是自己也親自嘗試了一下(感覺(jué)不容易上手)酥宴。寫(xiě)博客記錄下學(xué)習(xí)的過(guò)程啦吧,一方面作為鞏固,另一方面希望能幫助到初學(xué)者拙寡。
(第一篇只介紹了RxJava的基本用法授滓,暫時(shí)還無(wú)法看出RxJava的優(yōu)勢(shì)。切莫著急肆糕,隨著慢慢深入就能體會(huì)到RxJava帶來(lái)的方便了)

參考:給 Android 開(kāi)發(fā)者的 RxJava 詳解
(本文部分內(nèi)容引用自該博客)

介紹

在GitHub主頁(yè)上的介紹:

a library for composing asynchronous and event-based programs using observable sequences for the Java VM

翻譯過(guò)來(lái)就是:

一個(gè)在 Java VM 上使用可觀測(cè)的序列來(lái)組成異步的般堆、基于事件的程序的庫(kù)

對(duì)于新手們來(lái)說(shuō)這個(gè)太抽象了,我們(我也是新手)需要看到看到一個(gè)更加具體的解釋?zhuān)?jiǎn)單來(lái)說(shuō)诚啃,它就是一個(gè)實(shí)現(xiàn)異步操作的庫(kù)淮摔。(還是不懂?看代碼更實(shí)在)

優(yōu)點(diǎn)

RxJava的好處就在于它的簡(jiǎn)潔性始赎,邏輯簡(jiǎn)單的時(shí)候看不出RxJava的優(yōu)勢(shì)和橙,想必大家都知道在調(diào)度過(guò)程比較復(fù)雜的情況下仔燕,異步代碼經(jīng)常會(huì)既難寫(xiě)也難被讀懂。這時(shí)候RxJava的優(yōu)勢(shì)就來(lái)了魔招,隨著程序邏輯變得越來(lái)越復(fù)雜晰搀,它依然能夠保持簡(jiǎn)潔。

觀察者模式

首先要先介紹一下觀察者模式(可能比喻的不夠恰當(dāng)办斑,意思到了就好)厕隧;

  • 觀察者:監(jiān)視著被觀察者的行為,當(dāng)被觀察者某個(gè)狀態(tài)改變的時(shí)候會(huì)通知觀察者俄周,觀察者會(huì)執(zhí)行對(duì)應(yīng)的操作吁讨;
  • 被觀察者:被監(jiān)視的對(duì)象,當(dāng)某個(gè)狀態(tài)改變的時(shí)候會(huì)通知觀察者峦朗;
  • 訂閱(或注冊(cè)):將觀察者被觀察者建立聯(lián)系建丧。
    (很亂?來(lái)個(gè)栗子波势?)

這里舉一個(gè)我個(gè)常用的例子翎朱,點(diǎn)擊Button后觸發(fā)OnClickListener
中的onClick()事件。在這個(gè)事件中他們的角色分別如下:

  • 觀察者:OnClickListener尺铣;
  • 被觀察者:Button拴曲;
  • 訂閱(或注冊(cè)):setOnClickListener()。

RxJava

在上面介紹了觀察者模式凛忿,這里也將RxJava中的三個(gè)角色進(jìn)行一下角色分配

  • 觀察者:Observer澈灼;

  • 被觀察者:Observable;

  • 訂閱(或注冊(cè)):subscribe()店溢。

  • 觀察者
    Observer 即觀察者叁熔,它決定事件觸發(fā)的時(shí)候?qū)⒂性鯓拥男袨椤?br> RxJava 觀察者的事件回調(diào)方法除了普通事件onNext()(相當(dāng)于onClick()/onEvent())之外,還定義了兩個(gè)特殊的事件:onCompleted()和onError()床牧。

  • onCompleted(): 事件隊(duì)列完結(jié)荣回。RxJava 不僅把每個(gè)事件單獨(dú)處理,還會(huì)把它們看做一個(gè)隊(duì)列戈咳。RxJava 規(guī)定心软,當(dāng)不會(huì)再有新的onNext()發(fā)出時(shí),需要觸發(fā)onCompleted()方法作為標(biāo)志著蛙。
  • onError(): 事件隊(duì)列異常删铃。在事件處理過(guò)程中出異常時(shí),onError()
    會(huì)被觸發(fā)册踩,同時(shí)隊(duì)列自動(dòng)終止泳姐,不允許再有事件發(fā)出效拭。
  • 在一個(gè)正確運(yùn)行的事件序列中,onCompleted()和onError()有且只有一個(gè)暂吉,并且是事件序列中的最后一個(gè)胖秒。需要注意的是,onCompleted()
    和onError()二者也是互斥的慕的,即在隊(duì)列中調(diào)用了其中一個(gè)阎肝,就不應(yīng)該再調(diào)用另一個(gè)。
  • 被觀察者
    Observable 即被觀察者肮街,它決定什么時(shí)候觸發(fā)事件以及觸發(fā)怎樣的事件风题。可以使用create()嫉父、just(T...)沛硅、from(T[])或from(Iterable<? extends T>)來(lái)創(chuàng)建一個(gè) Observable ,并為它定義事件觸發(fā)規(guī)則绕辖。
  • 訂閱
    創(chuàng)建了Observable和Observer之后摇肌,再用subscribe()方法將它們聯(lián)結(jié)起來(lái)

直接看代碼吧,這里只展示了RxJava的基本用法仪际,暫時(shí)看不出RxJava的優(yōu)勢(shì)围小。

使用

例:打印機(jī)個(gè)字符串
添加依賴

compile 'io.reactivex:rxjava:1.0.14'
compile 'io.reactivex:rxandroid:1.0.1'
        //創(chuàng)建一個(gè)觀察者
        Observer<String> observer = new Observer<String>() {

            @Override
            public void onCompleted() {
                Log.i(TAG, "Completed");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "Error");
            }

            @Override
            public void onNext(String s) {
                Log.i(TAG, s);
            }
        };
        //使用Observable.create()創(chuàng)建被觀察者
        Observable observable1 = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Hello");
                subscriber.onNext("Wrold");
                subscriber.onCompleted();
            }
        });
        //訂閱
        observable1.subscribe(observer);

以上用到的都是rx包里面的,別用錯(cuò)了J骷睢?鲜省!


Observer

上面完成了一次Rxjava的基本使用成榜。

擴(kuò)展

  • Subscriber
    除了Observer接口之外框舔,RxJava 還內(nèi)置了一個(gè)實(shí)現(xiàn)了Observer的抽象:Subscriber。Subscriber對(duì)Observer接口進(jìn)行了一些擴(kuò)展赎婚,但他們的基本使用方式是完全一樣的:
Subscriber<String> subscriber = new Subscriber<String>() {
    @Override
    public void onNext(String s) {
        Log.d(tag, "Item: " + s);
    }

    @Override
    public void onCompleted() {
        Log.d(tag, "Completed!");
    }

    @Override
    public void onError(Throwable e) {
        Log.d(tag, "Error!");
    }
};

不僅基本使用方式一樣雨饺,實(shí)質(zhì)上,在 RxJava 的 subscribe 過(guò)程中惑淳,Observer也總是會(huì)先被轉(zhuǎn)換成一個(gè)Subscriber再使用额港。如圖:


Rxjava源碼

所以如果你只想使用基本功能,選擇Observer和Subscriber是完全一樣的歧焦。它們的區(qū)別對(duì)于使用者來(lái)說(shuō)主要有兩點(diǎn):

  • onStart(): 這是Subscriber增加的方法移斩。它會(huì)在 subscribe 剛開(kāi)始,而事件還未發(fā)送之前被調(diào)用绢馍,可以用于做一些準(zhǔn)備工作向瓷,例如數(shù)據(jù)的清零或重置。這是一個(gè)可選方法舰涌,默認(rèn)情況下它的實(shí)現(xiàn)為空猖任。需要注意的是,如果對(duì)準(zhǔn)備工作的線程有要求(例如彈出一個(gè)顯示進(jìn)度的對(duì)話框瓷耙,這必須在主線程執(zhí)行)朱躺,onStart()就不適用了刁赖,因?yàn)樗偸窃?subscribe 所發(fā)生的線程被調(diào)用,而不能指定線程长搀。要在指定的線程來(lái)做準(zhǔn)備工作宇弛,可以使用doOnSubscribe()方法,具體可以在后面的文中看到源请。
  • unsubscribe(): 這是Subscriber所實(shí)現(xiàn)的另一個(gè)接口Subscription
    的方法枪芒,用于取消訂閱。在這個(gè)方法被調(diào)用后谁尸,Subscriber將不再接收事件舅踪。一般在這個(gè)方法調(diào)用前,可以使用isUnsubscribed()先判斷一下?tīng)顟B(tài)良蛮。unsubscribe()這個(gè)方法很重要硫朦,因?yàn)樵趕ubscribe()之后,Observable會(huì)持有Subscriber的引用背镇,這個(gè)引用如果不能及時(shí)被釋放咬展,將有內(nèi)存泄露的風(fēng)險(xiǎn)。所以最好保持一個(gè)原則:要在不再使用的時(shí)候盡快在合適的地方(例如onPause()onStop()等方法中)調(diào)用unsubscribe()來(lái)解除引用關(guān)系瞒斩,以避免內(nèi)存泄露的發(fā)生破婆。
  • Observable
    Observable的其他幾種創(chuàng)建方法,一下Observable等價(jià)于之前使用Create()創(chuàng)建的Observable:
    1胸囱、使用Observable.just()創(chuàng)建被觀察者
Observable observable2 = Observable.just("Hello", "World");

2祷舀、使用Observable.from()創(chuàng)建被觀察者

String [] words = {"Hello", "World"};
Observable observable3 = Observable.from(words);

List<String> list = new ArrayList<String>();
list.add("Hellow");
list.add("Wrold");
Observable observable4 = Observable.from(list);

小結(jié)

目前沒(méi)看出RxJava的任何好處,感覺(jué)代碼還多了~~~
(別急烹笔,因?yàn)槭堑谝黄殉叮抑唤榻B了他們之間的關(guān)系以及最基礎(chǔ)的用法。后面的幾篇我會(huì)介紹RxJava的其他功能谤职,還有一些復(fù)雜的嵌套關(guān)系的處理饰豺,到時(shí)候知道RxJava的強(qiáng)大之處了)

更多:
Android RxJava的使用(二)Action
Android RxJava的使用(三)轉(zhuǎn)換(map、flatMap)
Android RxJava的使用(四)線程控制 —— Scheduler

以上有錯(cuò)誤之處感謝指出

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末允蜈,一起剝皮案震驚了整個(gè)濱河市冤吨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饶套,老刑警劉巖漩蟆,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異妓蛮,居然都是意外死亡怠李,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捺癞,“玉大人夷蚊,你說(shuō)我怎么就攤上這事∏檀兀” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵儿倒,是天一觀的道長(zhǎng)版保。 經(jīng)常有香客問(wèn)我,道長(zhǎng)夫否,這世上最難降的妖魔是什么彻犁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮凰慈,結(jié)果婚禮上汞幢,老公的妹妹穿的比我還像新娘。我一直安慰自己微谓,他們只是感情好森篷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著豺型,像睡著了一般仲智。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姻氨,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天钓辆,我揣著相機(jī)與錄音,去河邊找鬼肴焊。 笑死前联,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的娶眷。 我是一名探鬼主播似嗤,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼届宠!你這毒婦竟也來(lái)了双谆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤席揽,失蹤者是張志新(化名)和其女友劉穎顽馋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體幌羞,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寸谜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了属桦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眶诈,死狀恐怖层扶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诊笤,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布巾陕,位于F島的核電站讨跟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鄙煤。R本人自食惡果不足惜晾匠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梯刚。 院中可真熱鬧凉馆,春花似錦、人聲如沸亡资。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锥腻。三九已至咳胃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旷太,已是汗流浹背展懈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留供璧,地道東北人存崖。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像睡毒,于是被迫代替她去往敵國(guó)和親来惧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容