這可能是最好的RxJava 2.x 入門教程(三)

這可能是最好的 RxJava 2.x 入門教程系列專欄
文章鏈接:
這可能是最好的 RxJava 2.x 入門教程(完結版)【重磅推出】
這可能是最好的 RxJava 2.x 入門教程(一)
這可能是最好的 RxJava 2.x 入門教程(二)
這可能是最好的 RxJava 2.x 入門教程(三)
這可能是最好的 RxJava 2.x 入門教程(四)
這可能是最好的 RxJava 2.x 入門教程(五)
GitHub 代碼同步更新:https://github.com/nanchen2251/RxJava2Examples
為了滿足大家的饑渴難耐竖席,GitHub 將同步更新代碼养距,主要包含基本的代碼封裝,RxJava 2.x 所有操作符應用場景介紹和實際應用場景,后期除了 RxJava 可能還會增添其他東西,總之,GitHub 上的 Demo 專為大家傾心打造。傳送門:https://github.com/nanchen2251/RxJava2Examples

前言

年輕的老司機們,我這么勤的為大家分享弥虐,卻少有催更的,好吧媚赖。其實寫這個系列不是為了吸睛霜瘪,那咱們繼續(xù)寫我們的 RxJava 2.x 的操作符。

正題

distinct

這個操作符非常的簡單惧磺、通俗颖对、易懂,就是簡單的去重嘛豺妓,我甚至都不想貼代碼惜互,但人嘛,總得持之以恒琳拭。


 Observable.just(1, 1, 1, 2, 2, 3, 4, 5)
                .distinct()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("distinct : " + integer + "\n");
                        Log.e(TAG, "distinct : " + integer + "\n");
                    }
                });

輸出:


Log 日志顯而易見训堆,我們在經過 dinstinct() 后接收器接收到的事件只有1,2,3,4,5了。

Filter

信我白嘁,Filter 你會很常用的坑鱼,它的作用也很簡單,過濾器嘛÷沉ぃ可以接受一個參數呼股,讓其過濾掉不符合我們條件的值

Observable.just(1, 20, 65, -5, 7, 19)
                .filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(@NonNull Integer integer) throws Exception {
                        return integer >= 10;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                mRxOperatorsText.append("filter : " + integer + "\n");
                Log.e(TAG, "filter : " + integer + "\n");
            }
        });

輸出:



可以看到,我們過濾器舍去了小于 10 的值画恰,所以最好的輸出只有 20, 65, 19彭谁。

buffer

buffer 操作符接受兩個參數,buffer(count,skip)允扇,作用是將 Observable 中的數據按 skip (步長) 分成最大不超過 count 的 buffer 缠局,然后生成一個 Observable 。也許你還不太理解考润,我們可以通過我們的示例圖和示例代碼來進一步深化它狭园。

Observable.just(1, 2, 3, 4, 5)
                .buffer(3, 2)
                .subscribe(new Consumer<List<Integer>>() {
                    @Override
                    public void accept(@NonNull List<Integer> integers) throws Exception {
                        mRxOperatorsText.append("buffer size : " + integers.size() + "\n");
                        Log.e(TAG, "buffer size : " + integers.size() + "\n");
                        mRxOperatorsText.append("buffer value : ");
                        Log.e(TAG, "buffer value : " );
                        for (Integer i : integers) {
                            mRxOperatorsText.append(i + "");
                            Log.e(TAG, i + "");
                        }
                        mRxOperatorsText.append("\n");
                        Log.e(TAG, "\n");
                    }
                });

輸出:


如圖,我們把 1, 2, 3, 4, 5 依次發(fā)射出來糊治,經過 buffer 操作符唱矛,其中參數 skip 為 2, count 為 3井辜,而我們的輸出 依次是 123绎谦,345,5粥脚。顯而易見燥滑,我們 buffer 的第一個參數是 count,代表最大取值阿逃,在事件足夠的時候,一般都是取 count 個值赃蛛,然后每次跳過 skip 個事件恃锉。其實看 Log 日志,我相信大家都明白了呕臂。

timer

timer 很有意思破托,相當于一個定時任務。在 1.x 中它還可以執(zhí)行間隔邏輯歧蒋,但在 2.x 中此功能被交給了 interval土砂,下一個會介紹。但需要注意的是谜洽,timerinterval 均默認在新線程萝映。

mRxOperatorsText.append("timer start : " + TimeUtil.getNowStrTime() + "\n");
        Log.e(TAG, "timer start : " + TimeUtil.getNowStrTime() + "\n");
        Observable.timer(2, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()) // timer 默認在新線程,所以需要切換回主線程
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(@NonNull Long aLong) throws Exception {
                        mRxOperatorsText.append("timer :" + aLong + " at " + TimeUtil.getNowStrTime() + "\n");
                        Log.e(TAG, "timer :" + aLong + " at " + TimeUtil.getNowStrTime() + "\n");
                    }
                });

輸出:



顯而易見阐虚,當我們兩次點擊按鈕觸發(fā)這個事件的時候序臂,接收被延遲了 2 秒。

interval

如同我們上面可說实束,interval 操作符用于間隔時間執(zhí)行某個操作奥秆,其接受三個參數逊彭,分別是第一次發(fā)送延遲,間隔時間构订,時間單位侮叮。

mRxOperatorsText.append("interval start : " + TimeUtil.getNowStrTime() + "\n");
       Log.e(TAG, "interval start : " + TimeUtil.getNowStrTime() + "\n");
       Observable.interval(3,2, TimeUnit.SECONDS)
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread()) // 由于interval默認在新線程,所以我們應該切回主線程
               .subscribe(new Consumer<Long>() {
                   @Override
                   public void accept(@NonNull Long aLong) throws Exception {
                       mRxOperatorsText.append("interval :" + aLong + " at " + TimeUtil.getNowStrTime() + "\n");
                       Log.e(TAG, "interval :" + aLong + " at " + TimeUtil.getNowStrTime() + "\n");
                   }
               });

輸出:



如同 Log 日志一樣悼瘾,第一次延遲了 3 秒后接收到囊榜,后面每次間隔了 2 秒。
然而分尸,心細的小伙伴可能會發(fā)現锦聊,由于我們這個是間隔執(zhí)行,所以當我們的Activity 都銷毀的時候箩绍,實際上這個操作還依然在進行孔庭,所以,我們得花點小心思讓我們在不需要它的時候干掉它材蛛。查看源碼發(fā)現圆到,我們subscribe(Cousumer<? super T> onNext)返回的是Disposable,我們可以在這上面做文章卑吭。


@Override
   protected void doSomething() {
       mRxOperatorsText.append("interval start : " + TimeUtil.getNowStrTime() + "\n");
       Log.e(TAG, "interval start : " + TimeUtil.getNowStrTime() + "\n");
       mDisposable = Observable.interval(3, 2, TimeUnit.SECONDS)
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread()) // 由于interval默認在新線程芽淡,所以我們應該切回主線程
               .subscribe(new Consumer<Long>() {
                   @Override
                   public void accept(@NonNull Long aLong) throws Exception {
                       mRxOperatorsText.append("interval :" + aLong + " at " + TimeUtil.getNowStrTime() + "\n");
                       Log.e(TAG, "interval :" + aLong + " at " + TimeUtil.getNowStrTime() + "\n");
                   }
               });
   }

   @Override
   protected void onDestroy() {
       super.onDestroy();
       if (mDisposable != null && !mDisposable.isDisposed()) {
           mDisposable.dispose();
       }
   }

哈哈,再次驗證豆赏,解決了我們的疑惑挣菲。

doOnNext

其實覺得 doOnNext 應該不算一個操作符,但考慮到其常用性掷邦,我們還是咬咬牙將它放在了這里白胀。它的作用是讓訂閱者在接收到數據之前干點有意思的事情。假如我們在獲取到數據之前想先保存一下它抚岗,無疑我們可以這樣實現或杠。

Observable.just(1, 2, 3, 4)
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("doOnNext 保存 " + integer + "成功" + "\n");
                        Log.e(TAG, "doOnNext 保存 " + integer + "成功" + "\n");
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                mRxOperatorsText.append("doOnNext :" + integer + "\n");
                Log.e(TAG, "doOnNext :" + integer + "\n");
            }
        });

輸出:


skip

skip 很有意思,其實作用就和字面意思一樣宣蔚,接受一個 long 型參數 count 向抢,代表跳過 count 個數目開始接收。

Observable.just(1,2,3,4,5)
                .skip(2)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("skip : "+integer + "\n");
                        Log.e(TAG, "skip : "+integer + "\n");
                    }
                });

輸出:


take

take胚委,接受一個 long 型參數 count 挟鸠,代表至多接收 count 個數據。

Flowable.fromArray(1,2,3,4,5)
                .take(2)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("take : "+integer + "\n");
                        Log.e(TAG, "accept: take : "+integer + "\n" );
                    }
                });

輸出:


just

just篷扩,沒什么好說的兄猩,其實在前面各種例子都說明了,就是一個簡單的發(fā)射器依次調用 onNext() 方法。

Observable.just("1", "2", "3")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        mRxOperatorsText.append("accept : onNext : " + s + "\n");
                        Log.e(TAG,"accept : onNext : " + s + "\n" );
                    }
                });

輸出:


寫在最后

好吧枢冤,本節(jié)先講到這里鸠姨,下節(jié)我們還是繼續(xù)講簡單的操作符,雖然我們的教程比較枯燥淹真,現在也不那么受人關注讶迁,但后面的系列我相信大家一定會非常喜歡的,我們下期再見核蘸!
代碼全部同步到GitHub:https://github.com/nanchen2251/RxJava2Examples

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末巍糯,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子客扎,更是在濱河造成了極大的恐慌祟峦,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徙鱼,死亡現場離奇詭異宅楞,居然都是意外死亡,警方通過查閱死者的電腦和手機袱吆,發(fā)現死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門厌衙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绞绒,你說我怎么就攤上這事婶希。” “怎么了蓬衡?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵喻杈,是天一觀的道長。 經常有香客問我狰晚,道長奕塑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任家肯,我火速辦了婚禮,結果婚禮上盟猖,老公的妹妹穿的比我還像新娘讨衣。我一直安慰自己,他們只是感情好式镐,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布反镇。 她就那樣靜靜地躺著,像睡著了一般娘汞。 火紅的嫁衣襯著肌膚如雪歹茶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音惊豺,去河邊找鬼燎孟。 笑死,一個胖子當著我的面吹牛尸昧,可吹牛的內容都是我干的揩页。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼烹俗,長吁一口氣:“原來是場噩夢啊……” “哼爆侣!你這毒婦竟也來了?” 一聲冷哼從身側響起幢妄,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤兔仰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蕉鸳,有當地人在樹林里發(fā)現了一具尸體乎赴,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年置吓,在試婚紗的時候發(fā)現自己被綠了无虚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡衍锚,死狀恐怖友题,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情戴质,我是刑警寧澤度宦,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站告匠,受9級特大地震影響戈抄,放射性物質發(fā)生泄漏。R本人自食惡果不足惜后专,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一划鸽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧戚哎,春花似錦裸诽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至甘畅,卻和暖如春埂蕊,著一層夾襖步出監(jiān)牢的瞬間往弓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工蓄氧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留函似,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓匀们,卻偏偏與公主長得像缴淋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泄朴,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容