RxJava 2.0(一)簡介

RxJava基礎(chǔ)

使用RxJava之前疆前,先了解四個基本概念:

  • Observable:被觀察者
  • Observer:觀察者
  • subscribe:訂閱
  • 事件

工作流程:

RxJava采用的是觀察者模式蹂季,首先建立被觀察者Observable和觀察者Observer沼撕,他們通過subscribe來建立聯(lián)系(Observable.subscribe(Observer))蒸矛,然后Observable在特定的時刻(完成某些操作考余,獲得返回結(jié)果等)可以發(fā)送事件給Observer技即,Observer根據(jù)接收到的事件作出相應(yīng)的動作未蝌。

來看一個簡單的例子:

//創(chuàng)建被觀察者
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                //執(zhí)行一些其他操作
                //.............
                //執(zhí)行完畢蔽午,觸發(fā)回調(diào)易茬,通知觀察者
                e.onNext("事件");
            }
        });
//創(chuàng)建觀察者
Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            //觀察者接收到通知,進(jìn)行相關(guān)操作
            public void onNext(String aLong) {
                System.out.println("收到事件");
            }
            @Override
            public void onError(Throwable e) {
            }
            @Override
            public void onComplete() {
            }
        };
//訂閱
observable.subscribe(observer);

這就是一個完整的RxJava觀察者模式。被觀察者的創(chuàng)建使用 Observable.create,內(nèi)部實(shí)現(xiàn)了subscribe方法抽莱。一旦Observable被訂閱(observable.subscribe(observer))范抓,subscribe方法就會被調(diào)用,開始發(fā)送事件食铐。

事件的發(fā)送由ObservableEmitter來完成匕垫,Emitter是事件的發(fā)送者,可以調(diào)用它的onNext(), onComplete(), onError()方法來發(fā)送不同的事件虐呻。

觀察者Observer包含四個方法:onSubscribe方法在訂閱完成以后象泵,第一個onNext事件之前調(diào)用,只調(diào)用一次斟叼。其他三個方法則由被觀察者決定是否調(diào)用偶惠。

onSubscribe方法接收一個Disposable對象作為參數(shù),它用來切斷observable和observer之間的聯(lián)系朗涩。一旦調(diào)用了Disposable對象的dispose()方法忽孽,observer就停止動作,不再響應(yīng)觀察對象發(fā)送的事件了谢床。

將上面的例子加工一下兄一,驗(yàn)證Disposable的作用:

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("a");
                e.onNext("b");
                e.onNext("c");
            }
        })
                .subscribe(new Observer<String>() {
                    private Disposable mDisposable;
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d("RxJava", "onSubscribe" );
                        mDisposable = d;
                    }
                    @Override
                    public void onNext(@NonNull String s) {
                        Log.d("RxJava", "Received Message: " + s );
                        if (s.equals("b")) mDisposable.dispose();
                    }
                    @Override
                    public void onError(@NonNull Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                        Log.d("RxJava", "onComplete" );
                    }
                });

代碼做了一點(diǎn)修改,采用鏈?zhǔn)讲僮魇锻龋雌饋砀啙嵰恍┏龈铮硗獍l(fā)送完第二個事件之后,調(diào)用了dispose方法覆履√E瑁可以看到運(yùn)行結(jié)果如下:

D/RxJava: onSubscribe
D/RxJava: Received Message: a
D/RxJava: Received Message: b

介紹到這里,整個RxJava的工作流程就完成了硝全∑芪恚總結(jié)一下事件的發(fā)送和接收規(guī)則:

  • onNext()事件不限制發(fā)送次數(shù),被觀察者可以發(fā)送無限多個onNext伟众,下游也可以接收無限多個onNext
  • onComplete()/onError()并不會自動發(fā)送析藕,需要被觀察者指定什么時間發(fā)送
  • onComplete()/onError()發(fā)送之后,被觀察者仍然可以繼續(xù)發(fā)送事件凳厢,但是觀察者接收到onComplete()/onError()之后就不再接收事件了账胧。
  • onComplete()/onError()是唯一且互斥的。也就是說先紫,發(fā)送的事件中治泥,只能存在一個onComplete()或者onError()。否則可能會引起崩潰
  • dispose()方法可以在觀察者一端決定是夠繼續(xù)接收事件

Observable創(chuàng)建

在上面的例子中創(chuàng)建Observable使用的是create方法遮精,除此之外居夹,還有其他不同的創(chuàng)建方法:

  • just
    使用該方式創(chuàng)建的Observable對象在創(chuàng)建完成后會自動調(diào)用onNext方法败潦,依次發(fā)送創(chuàng)建時傳入的數(shù)據(jù)。
Observable<String> observable = Observable.just("aa","bb","cc");
  • fromIterable
    這種方式接收一個List集合作為參數(shù)准脂,創(chuàng)建完成后會遍歷該集合并調(diào)用onNext方法來發(fā)送數(shù)據(jù):
List<String> list = new ArrayList<>() ;
        list.add( "aa" ) ;
        list.add( "bb" ) ;
        list.add( "cc" ) ;
  Observable<String> observable2 = Observable.fromIterable(list) ;
  • defer
    defer是推遲的意思劫扒,observable在觀察者進(jìn)行訂閱的時候才創(chuàng)建對象,針對每一個觀察者狸膏,都會創(chuàng)建一個新的observable對象:
Observable<String> observable4 = Observable.defer(new Callable<ObservableSource<? extends String>>() {
            @Override
            public ObservableSource<? extends String> call() throws Exception {
                return Observable.just("aa" , "bb" , "cc");
            }
        });
  • interval
    采用該方式創(chuàng)建的observable會按照指定的時間間隔沟饥,從0開始發(fā)送整數(shù)序列。
//每隔兩秒發(fā)送一個整數(shù)
Observable.interval(2, TimeUnit.SECONDS).subscribe(new Consumer<Long>() {
            @Override
            public void accept(@NonNull Long aLong) throws Exception {
                Log.d("RxJava", "accept " + aLong );
            }
        });
  • range
    range接收兩個整型參數(shù)湾戳,第一個表示起始值贤旷,第二個表示發(fā)送次數(shù)N。observable會從初始值開始院塞,調(diào)用N次onNext遮晚,發(fā)送數(shù)據(jù)從初始值開始依次加1.
Observable.range(10, 20).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                Log.d("RxJava", "accept1 " + integer );//輸出結(jié)果為10,11,12,......29
            }
        });
  • timer
    observable在指定的時間發(fā)送事件調(diào)用onNext:
//表示5秒后發(fā)送事件
        Observable.timer(5, TimeUnit.SECONDS).subscribe(new Consumer<Long>() {
            @Override
            public void accept(@NonNull Long aLong) throws Exception {
                Log.d("RxJava", "timer  " + aLong );//默認(rèn)發(fā)送值為0
            }
        });
  • repeat
    repeat修飾的observable對象可以重復(fù)發(fā)送事件,并且可以指定重復(fù)次數(shù)拦止。如果不指定县遣,默認(rèn)為一直重復(fù)。
Observable.timer(5, TimeUnit.SECONDS).repeat()//.repeat(3);

Observer創(chuàng)建

Observer的創(chuàng)建很簡單汹族,上面的例子中已經(jīng)給出來了:

Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            //觀察者接收到通知,進(jìn)行相關(guān)操作
            public void onNext(String aLong) {
                System.out.println("收到事件");
            }
            @Override
            public void onError(Throwable e) {
            }
            @Override
            public void onComplete() {
            }
        };

為了代碼簡潔易讀萧求,通常會在訂閱的時候直接創(chuàng)建Observer,訂閱的方法subscribe有以下幾種重載:

    public final Disposable subscribe() {}/
    public final Disposable subscribe(Consumer<? super T> onNext) {}
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {} 
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
    public final void subscribe(Observer<? super T> observer) {}

最開始的例子中顶瞒,采用的是最后一種方法夸政,傳入一個Observer對象。
不帶參數(shù)的subscribe榴徐,第一種方法守问,表示Observable負(fù)責(zé)發(fā)送數(shù)據(jù),但是沒有觀察者去接收坑资。
只有一個參數(shù)Consumer<? super T> onNext表示Observer只需要處理onNext 方法耗帕。剩余的幾種重載同理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末袱贮,一起剝皮案震驚了整個濱河市仿便,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌攒巍,老刑警劉巖嗽仪,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柒莉,居然都是意外死亡闻坚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門兢孝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲤氢,“玉大人搀擂,你說我怎么就攤上這事【碛瘢” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵喷市,是天一觀的道長相种。 經(jīng)常有香客問我,道長品姓,這世上最難降的妖魔是什么寝并? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮腹备,結(jié)果婚禮上衬潦,老公的妹妹穿的比我還像新娘。我一直安慰自己植酥,他們只是感情好镀岛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著友驮,像睡著了一般漂羊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卸留,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天走越,我揣著相機(jī)與錄音,去河邊找鬼耻瑟。 笑死旨指,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的喳整。 我是一名探鬼主播谆构,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼算柳!你這毒婦竟也來了低淡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瞬项,失蹤者是張志新(化名)和其女友劉穎蔗蹋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囱淋,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猪杭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了妥衣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皂吮。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡戒傻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜂筹,到底是詐尸還是另有隱情需纳,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布艺挪,位于F島的核電站不翩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏麻裳。R本人自食惡果不足惜口蝠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望津坑。 院中可真熱鬧妙蔗,春花似錦、人聲如沸疆瑰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乃摹。三九已至禁漓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孵睬,已是汗流浹背播歼。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掰读,地道東北人秘狞。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像蹈集,于是被迫代替她去往敵國和親烁试。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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