筆記:RxJava(一)

學習RxJava,做一下筆記
筆記:RxJava(二)

1、描述

  1. RxJava是一個基于事件流的實現異步操作的庫,類似Androidhandler、AsyncTask
  2. 隨著程序邏輯變得越來越復雜,它依然能夠保持簡潔
  3. RxJava 的異步實現,是通過一種擴展的觀察者模式來實現的
  4. 觀察模式可實現回調,采用訂閱Subscribe的方式將被觀察者Observable與觀察者Observer鏈在一起,實現訂閱關系,進行消息事件的通知

2、依賴地址


3、簡單創建用法與理解

3.1、Observable.create(ObservsbleOnSubscribe)的使用

        /**
         * 一、創建  可觀察者(Observable )  以及   生產事件
         *
         *
         * 1. 創建可觀察者 Observable 對象,可觀察的數據類型為String
         * 2.create() 是 RxJava 最基本的創造事件序列的方法,還有just(多個數據)、from(數據數組)等
         * 3.create(ObservableOnSubscribe)此處一個ObservableOnSubscribe對象參數
         * 4.當 Observable 被訂閱時,OnSubscribe 的 call() 方法會自動被調用,即事件序列就會依照設定依次被觸發
         *      也就是只有被訂閱時,事件才會發送
         */
        Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
                /**
                 *  1.重寫的subscribe(),自定義需要發送的事件
                 *  2. 通過 ObservableEmitter類對象,事件發射器,產生事件并通知觀察者
                 */
                emitter.onNext("test1");
                emitter.onNext("test2");
                emitter.onNext("test3");
                emitter.onNext("test4");
                emitter.onComplete();
//=====================================>>>>>>>>>>關注①
                //emitter.onNext("test1");
                //emitter.onNext("test2");
                //emitter.onNext("test3");
                //emitter.onComplete();
                //emitter.onNext("test4");  
// =====================================>>>>>>>>>>關注②
//                emitter.onNext("test1");
//                emitter.onNext("test2");
//                emitter.onError(new Throwable("onError"));
//                emitter.onNext("test3");
//                emitter.onComplete();
//                emitter.onNext("test4");
            }
        });
        /**
         *
         * 二、創建   觀察者 (Observer )以及 自定義響應事件的行為
         *
         *
         * 1. 創建觀察者 (Observer )對象,觀察數據對象為String
         * 2. 自動復寫對應事件的方法 從而 響應對應的事件
         *
         *
         */
        Observer<String> observer=new Observer<String>() {
            // 觀察者接收事件之前,默認最先調用復寫 onSubscribe()這個方法
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d("TAG", "開始subscribe連接,接收上游可觀察者(Observable)的事件");
            }

            /**
             *  當可觀察者生產Next事件 這里的 觀察者接收到時,會調用該復寫這個方法 進行事件響應,可接收多個Next事件,
             *  直到接收到上游可觀察者onComplete/onError事件,其中onComplete/onError事件是唯一的,兩者之間是互斥的
             */
            @Override
            public void onNext(@NonNull String s) {
                Log.d("TAG", "接收到Next事件=="+s);
            }
            /**
             * 當可觀察者生產Error事件并且 觀察者接收到時,會調用該復寫這個方法 進行響應
             * 當觀察者接收到可觀察者發過來的onError事件時,觀察者不再接收事件了,但 可觀察者可以繼續發送事件
             * onError事件與onComplete事件時互斥的,兩者只能有其一
             */
            @Override
            public void onError(@NonNull Throwable e) {
                Log.d("TAG", "接收到onError事件=="+e.toString());
            }
            // 當被觀察者生產Complete事件& 觀察者接收到時,會調用該復寫方法 進行響應
            @Override
            public void onComplete() {
                Log.d("TAG", "接收到onComplete事件");
            }
        };

        /**
         *
         * 三、通過訂閱(Subscribe)連接觀察者和被觀察者
         *
         * 就好比可觀察者為上游的出水水管,觀察者為下游接水水管,中間通過Subscribe連接,水就可以通了
         * 此時事件可產生,發射,接收
         */
        observable.subscribe(observer);

打印的log如下圖
1525324457(1).png

關注① 當接收到了onComplete事件后,接收者Observer不再接收后面的事件,但可觀察者Observable依然會發射事件

打印log結果

1525324655(1).jpg

關注② 當接收到了onError事件后,接收者Observer不再接收后面的事件,但可觀察者Observable依然會發射事件

1525325319(1).jpg

3.1.1、RxJava的基于事件流的鏈式使用

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("test1");
                emitter.onNext("test2");
                emitter.onNext("test3");
                emitter.onComplete();
                emitter.onError(new Throwable("onError"));
                emitter.onNext("test4");
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                //====================================>>>>>>>>>>>關注③
                Log.e("TAG", "開始subscribe連接,接收上游可觀察者(Observable)的事件");
            }

            @Override
            public void onNext(@NonNull String s) {
                Log.e("TAG", "接收到Next事件==" + s);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e("TAG", "接收到onError事件==" + e.toString());
            }

            @Override
            public void onComplete() {
                Log.e("TAG", "接收到onComplete事件");
            }
        });
    }
}

打印log結果:接收了 test1、test2、test3和onComplete事件

1525326244(1).jpg

關注③ 可采用 Disposable.dispose() 切斷觀察者 與 被觀察者 之間的連接

public class MainActivity extends AppCompatActivity {
    // 定義Disposable類變量
    private Disposable mDisposable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("test1");
                emitter.onNext("test2");
                emitter.onNext("test3");
                emitter.onNext("test4");
                emitter.onComplete();
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                //  對Disposable類變量賦值
                mDisposable=d;
                Log.e("TAG", "開始接收上游可觀察者(Observable)的事件");
            }

            @Override
            public void onNext(@NonNull String s) {
                Log.e("TAG", "接收到Next事件==" + s);
                /**
                 * 當接收的事件為test2的時候,切斷觀察者 與 可觀察者 之間的連接
                 * 即觀察者 不再繼續 接收 可觀察者發送的事件,但可觀察者還是可以繼續發送事件
                 * 
                 * 就好比可觀察者為上游的出水水管,觀察者為下游接水水管,中間通過Subscribe連接,現在將兩個水管的交接出去掉
                 * 下游不再可以接收水,上游卻可以繼續出水
                 */

                if (s.equals("test2")){
                    mDisposable.dispose();
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e("TAG", "接收到onError事件==" + e.toString());
            }

            @Override
            public void onComplete() {
                Log.e("TAG", "接收到onComplete事件");
            }
        });
    }
}

Log打印結果:下圖可看出,當接收的事件為test2事件后,觀察者不再接收后面的事件,連onComplete事件也不再接收,但此時,可觀察者依然在繼續發送事件

1525327664(1).jpg

3.2、RxJava其他簡單創建用法

3.2.1、just(Object)的使用

1、快速的創建可觀察者對象
2、直接發送 傳入的事件(參數)轉化為Observable對象
3、最多只能發送10個參數
4、將傳入的參數依次發射出來
5、與 fromXxx( T[] ) / fromXxx( Iterable<? extends T> )用法很接近,參數前者是一個一個的,后者是數組T[]的形式 / Iterable 拆分成的具體對象
6、不那么準確的說 fromArray( T[] )just(Object) 的加強版

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Observable
                .just("test1","test2","test3","test4","test5","test6","test7","test8","test9","test10")
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e("TAG", "開始接收上游可觀察者(Observable)的事件");
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.e("TAG", "接收到Next事件==" + s);

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e("TAG", "接收到onError事件==" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });
    }
}

log打印結果:

1525331916(1).jpg

3.2.2、fromArray( T [ ] )的簡單使用

1、 可發送10個以上事件(數組形式)
2、不那么準確的說 fromArray( T[] )just(Object) 的加強版
3、與 fromXxx( T[] ) / fromXxx( Iterable<? extends T> )用法很接近
4、與 fromIterable( list )用法很接近
5、fromArray( T[] ) 的參數是一個數組,將數組中的數據轉換為一個個Observable對象
6、若傳入一個list集合,會直接把list當做一個數據元素,轉換為Observable對象發送出去,示例看關注④

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**
         *  設置需要傳入的數組
         * 快速創建Observable對象
         */
        String[] items = {"test1","test2","test3","test4","test5","test6","test7","test8","test9","test10"};
        Observable
                .fromArray(items)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e("TAG", "開始接收上游可觀察者(Observable)的事件");
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.e("TAG", "接收到Next事件==" + s.toString());

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e("TAG", "接收到onError事件==" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });

log打印結果 :

1525334420(1).jpg

關注④ fromArray() 傳入一級list集合,會將這個集合轉換為一個Observable對象

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**
         *  設置需要傳入的數組
         * 快速創建Observable對象
         */
        String[] items = {"test1","test2","test3","test4","test5","test6","test7","test8","test9","test10"};
        List<String> list=new ArrayList<>();
        for (String item:items){
            list.add(item);
        }
        
        Observable
                .fromArray(list)
                .subscribe(new Observer<List>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e("TAG", "開始接收上游可觀察者(Observable)的事件");
                    }

                    @Override
                    public void onNext(@NonNull List s) {
                        Log.e("TAG", "接收到Next事件==" + s.toString());

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e("TAG", "接收到onError事件==" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });

下面是參數為 數組 與參數為 list 的log打印結果:

1525334859(1).jpg

3.2.2.1、額外說明:此處參考文章來自---------Android Rxjava:這是一篇 清晰 & 易懂的Rxjava 入門教程

    public final Disposable subscribe() {}
    // 表示觀察者不對被觀察者發送的事件作出任何響應(但可觀察者還是可以繼續發送事件)

    public final Disposable subscribe(Consumer<? super T> onNext) {}
    // 表示觀察者只對被觀察者發送的Next事件作出響應
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {} 
    // 表示觀察者只對被觀察者發送的Next事件 & Error事件作出響應

    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
    // 表示觀察者只對被觀察者發送的Next事件、Error事件 & Complete事件作出響應

    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
    // 表示觀察者只對被觀察者發送的Next事件、Error事件 、Complete事件 & onSubscribe事件作出響應

    public final void subscribe(Observer<? super T> observer) {}
    // 表示觀察者對被觀察者發送的任何事件都作出響應

3.2.3、fromIterable( list )的簡單使用

與前面幾個類似,參數是集合list,用法跟前面幾個一樣,這里就不說明了,需要的話就看前面幾個的說明

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**
         *  設置需要傳入的數組
         * 快速創建Observable對象
         */
        String[] items = {"test1","test2","test3","test4","test5","test6","test7","test8","test9","test10"};
        List<String> list=new ArrayList<>();
        for (String item:items){
            list.add(item);
        }

        Observable
                .fromIterable(list)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e("TAG", "開始接收上游可觀察者(Observable)的事件");
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.e("TAG", "接收到Next事件==" + s);

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e("TAG", "接收到onError事件==" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });

log打印結果:

image.png

3.3、defer()的簡單使用

1、在經過了x秒后,需要自動執行y操作
2、每隔x秒后,需要自動執行y操作

3.4、timer()的簡單使用

1、延遲指定時間后,發送1個數值0(Long類型)
2、原理:延遲指定時間后,調用一次 onNext(0)
3、發送一個0,一般用于檢測
4、timer操作符默認運行在一個新線程上,既然可以默認也可以自定義,timer(long,TimeUnit,Scheduler)第三個參數可自定義線程,指定timer的運行線程

// 延遲1s后,發送一個long類型數值
        Observable.timer(1, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e("TAG", "開始連接");
                    }

                    @Override
                    public void onNext(Long value) {
                        Log.e("TAG", "onNext=="+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收到onError事件");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }

                });

log打印結果:先是打印 開始連接 ,1s后,再打印onNext==0 接收到onComplete事件

1525339570(1).jpg

3.5、interval()的簡單使用

1、快速創建1個被觀察者對象(Observable
2、每隔指定時間 就發送 事件
3、發送的事件序列 = 從0開始、無限遞增1的的整數序列

         /**
         * 
         * 延遲3s后發送事件,每隔1秒產生1個數字(從0開始遞增1,無限個)
         * 
         * 
         * 參數1 = 第1次延遲時間;
         * 參數2 = 間隔時間數字;
         * 參數3 = 時間單位;
         */
        Observable.interval(3,1,TimeUnit.SECONDS)
                
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e("TAG", "開始連接");
                    }
                    // 默認最先調用復寫的 onSubscribe()

                    @Override
                    public void onNext(Long value) {
                        Log.e("TAG", "接收onNext事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收onError事件"+e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收onComplete事件");
                    }

                });

log打印結果:第一次打印開始連接 ,3s后,打印 接收onNext事件0, 之后每隔一秒打印一個接收onNext事件1........N 無限遞增

3.6、intervalRange()的簡單使用

1、快速創建1個被觀察者對象(Observable
2、每隔指定時間 就發送 事件,可指定發送的數據的數量
3、發送的事件序列 = 從0開始、遞增1的的整數序列
4、. 作用類似于interval(),但可指定發送的數據的數量


 /**
         * 從3開始,一共發送10個事件,第1次延遲2s發送,之后每隔2秒產生1個數字
         * 
         * 
         * 參數1 = 事件序列起始點
         * 參數2 = 事件數量
         * 參數3 = 第1次事件延遲發送時間
         * 參數4 = 間隔時間數字
         * 參數5 = 時間單位
         */

        Observable.intervalRange(3,10,2, 1, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e("TAG", " 開始連接");
                    }

                    @Override
                    public void onNext(Long value) {
                        Log.e("TAG", " 接收onNext事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", " 接收onError事件"+e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", " 接收onComplete事件");
                    }

                });
1525341993(1).jpg

3.7、range()的簡單使用

1、快速創建1個被觀察者對象(Observable
2、連續發送 1個事件序列,可指定范圍
3、發送的事件序列 = 從0開始、遞增1的的整數序列
4、作用類似于intervalRange(),但區別在于:無延遲發送事件

        /**
         * 從4開始發送,每次發送事件遞增1,一共發送5個事件
         *
         * 參數1 = 事件序列起始點
         * 參數2 = 事件數量
         * 注:若設置為負數,則會拋出異常
         */

        Observable.range(4,5)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e("TAG", "開始連接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.e("TAG", "接收到了事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收onError事件"+e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收onComplete事件");
                    }

                });

log打印結果:

1525341057(1).jpg

4、RXJava常用操作符的簡單使用*

4.1、變換操作符

①、map() 將事件序列中的對象或整個序列進行加工轉換,將可觀察者要發送的事件轉換為任意的類型事件。
②、Flatmap()
③、ConcatMap()
④、Buffer()

4.1.1、Map()簡單使用

1、說明: 將事件序列中的對象或整個序列進行加工處理,轉換成不同的事件或事件序列,不準確的說,就是 傳進去的值被轉換了,返回的返回值不同了,將可觀察者要發送的事件轉換為任意的類型事件。

Observable.create(new ObservableOnSubscribe<Integer>() {

                    // 可觀察者發送事件 = 參數為整型 = 1、2、3
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onNext(3);
                    }
                })
                // 使用Map變換操作符中的Function函數對可觀察者發送的事件
                // 進行統一變換:將整型變換成字符串類型
                .map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return "使用 Map變換操作符 將事件" + integer +"的參數從 整型"
                                +integer + " 變換成 字符串類型" + integer ;
                    }
                })
                .subscribe(new Consumer<String>() {
                    // 觀察者接收事件時,是接收到變換后的事件 = 字符串類型
                    @Override
                    public void accept(String s) throws Exception {
                        Log.e("TAG", s);
                    }
                });

log打印結果:

1525402785(1).jpg

4.1.2、FlatMap()簡單使用

  • 將被觀察者發送的事件序列進行 拆分 & 單獨轉換,再合并成一個新的事件序列,最后再進行發送
  • 無序的將被觀察者發送的整個事件序列進行變換
  // 采用RxJava基于事件流的鏈式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
            }

            // 采用flatMap()變換操作符
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
//                final List<String> list = new ArrayList<>();
//                for (int i = 0; i < 3; i++) {
//                    list.add("我是事件 " + integer + "拆分后的子事件" + i);
//                    // 通過flatMap中將可觀察者發送的事件序列先進行拆分,再將每個事件轉換為一個新的Observable,再發送給出去
//                    // 最終合并,再發送給被觀察者
//                return Observable.fromIterable(list);
//                }

                //這里會生成新的可觀察者,然后與觀察者訂閱,像一種代理機制,通過事件攔截和處理實現事件序列的變換。
                return Observable.just("事件 " + integer + " 轉換成的子事件 " + "test"+integer);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.e("TAG", s);
            }
        });

log打印結果:

image.png

4.1.3、concatMap()簡單使用

  • 將被觀察者發送的事件序列進行 拆分 & 單獨轉換,再合并成一個新的事件序列,最后再進行發送
  • 無序的將被觀察者發送的整個事件序列進行變換
  • 用法和flatMap()相同,只是場景不同
  • 新合并生成的事件序列順序是有序的,即 嚴格按照舊序列發送事件的順序
 // 采用RxJava基于事件流的鏈式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
            }

            // 采用concatMap()變換操作符
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                //                final List<String> list = new ArrayList<>();
                //                for (int i = 0; i < 3; i++) {
                //                    list.add("我是事件 " + integer + "拆分后的子事件" + i);
                //                    // 通過concatMap中將可觀察者發送的事件序列先進行拆分,再將每個事件轉換為一個新的Observable,再發送給出去
                //                    // 最終合并,再發送給被觀察者
                //                return Observable.fromIterable(list);
                //                }

                //這里會生成新的可觀察者,然后與觀察者訂閱,像一種代理機制,通過事件攔截和處理實現事件序列的變換。
                return Observable.just("事件 " + integer + " 轉換成的子事件 " + "test"+integer);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.e("TAG", s);
            }
        });

log打印結果:

image.png

4.1.4、Buffer()簡單使用

  • 場景:緩存被觀察者發送的事件
  • 作用:定期從可觀察者(Obervable)需要發送的事件中 獲取一定數量的事件 & 放到緩存區中,最終發送
// 被觀察者 需要發送5個數字
        Observable.just(1, 2, 3, 4, 5)
                .buffer(3, 1) // 設置緩存區大小 & 步長
                // 緩存區大小 = 每次從被觀察者中獲取的事件數量
                // 步長 = 每次獲取新事件的數量
                .subscribe(new Observer<List<Integer>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }
                    @Override
                    public void onNext(List<Integer> stringList) {
                        //
                        Log.e("TAG", " 緩存區里的事件數量 = " +  stringList.size());
                        for (Integer value : stringList) {
                            Log.e("TAG", " 接收onNext事件 = " + value);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收onError事件" );
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收Complete事件");
                    }
                });

log打印結果:

image.png

4.2、concat() / concatArray()組合多個可觀察者

① 組合多個被觀察者一起發送數據,合并后 按發送順序串行執行
concat() / concatArray()二者區別:組合被觀察者的數量,即concat()組合被觀察者數量≤4個,而concatArray()則可>4個

4.2.1、concat()

concat():組合多個被觀察者(≤4個)一起發送數據

    // 串行執行
        Observable
                .concat(

                        Observable.just(1, 2, 3),
                        Observable.just(4, 5, 6),
                        Observable.just(7, 8, 9),
                        Observable.just(10, 11, 12)
                )
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.e("TAG", "接收到onNext事件==" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收到onError事件"+e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });

log打印結果:

image.png

4.2.2、concatArray()

concat():組合多個被觀察者(≤4個)一起發送數據
concatArray():組合多個被觀察者一起發送數據(可>4個)

        // 串行執行
        Observable.concatArray(Observable.just(1, 2, 3),
                Observable.just(4, 5, 6),
                Observable.just(7, 8, 9),
                Observable.just(10, 11, 12),
                Observable.just(13, 14, 15))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.e("TAG", "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "對Error事件作出響應");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "對Complete事件作出響應");
                    }
                });

log打印結果:

image.png

4.3、merge() / mergeArray()簡單使用

① 組合多個可觀察者一起發送數據,合并后 按時間線并行執行
② 二者區別:組合可觀察者的數量,即merge()組合可觀察者數量≤4個,而mergeArray()則可>4個
③ 區別上述concat()操作符:同樣是組合多個可觀察者一起發送數據,但concat()操作符合并后是按發送順序串行執行

4.3.1、merge()簡單使用

merge():組合多個可觀察者(≤ 4個)一起發送數據

//合并后按照時間線并行執行
        Observable.merge(
                Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 從0開始發送、共發送3個數據、第1次事件延遲發送時間 = 1s、間隔時間 = 1s
                Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS)) // 從2開始發送、共發送3個數據、第1次事件延遲發送時間 = 1s、間隔時間 = 1s
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        Log.e("TAG", "接收到onNext事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收到onError事件");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });

log打印結果:輸出結果 = 事件0,事件2 -> 事件1,事件3 -> 事件2,事件4

image.png

4.3.2、mergeArray()簡單使用

mergeArray():組合多個可觀察者(≤ 4個)一起發送數據

Observable.mergeArray(
                Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 從0開始發送、共發送3個數據、第1次事件延遲發送時間 = 1s、間隔時間 = 1s
                Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS)) // 從2開始發送、共發送3個數據、第1次事件延遲發送時間 = 1s、間隔時間 = 1s
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        Log.e("TAG", "mergeArray--接收到onNext事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "mergeArray--接收到onError事件");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "mergeArray--接收到onComplete事件");
                    }
                });

log打印結果:輸出結果 = 事件0,事件2 -> 事件1,事件3 -> 事件2,事件4

image.png

4.4、concatDelayError() / mergeDelayError()簡單使用

  • 使用concat()和merge()操作符時,其中1個可觀察者發出onError事件,則會馬上終止其他可觀察者繼續發送事件,如果希望onError事件推遲到其他可觀察者發送事件結束才再觸發發送onError事件,可使用concatDelayError()或者mergeDelayError操作符來解決
Observable.concat( //沒有使用concatDelayError()的情況 
                
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {

                        emitter.onNext(1);
                        emitter.onError(new NullPointerException()); // 發送Error事件,因為無使用concatDelayError,所以第2個Observable將不會發送事件
                        emitter.onNext(2);
                        emitter.onNext(3);
                        emitter.onComplete();
                    }
                }),
                Observable.just(4, 5, 6))//沒有使用了concatDelayError(),事件4、5、6在onError事件后不再發射
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }
                    @Override
                    public void onNext(Integer value) {
                        Log.e("TAG", " 接收到事件 "+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "接收到onError事件");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "接收到onComplete事件");
                    }
                });
        
 
                Observable.concatArrayDelayError(//使用了concatDelayError()的情況
                        
                        Observable.create(new ObservableOnSubscribe<Integer>() {
                            @Override
                            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {

                                emitter.onNext(1);
                                emitter.onError(new NullPointerException()); // 發送Error事件,因為使用了concatDelayError,所以第2個Observable將會發送事件,等發送完畢后,再發送錯誤事件
                                emitter.onNext(2);
                                emitter.onNext(3);
                                emitter.onComplete();
                            }
                        }),
                        Observable.just(4, 5, 6))//使用了concatDelayError(),事件4、5、6在onError事件后可以發射
                        .subscribe(new Observer<Integer>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }
                            @Override
                            public void onNext(Integer value) {
                                Log.e("TAG", "接收到了事件"+ value  );
                            }

                            @Override
                            public void onError(Throwable e) {
                                Log.e("TAG", "接收到了onError事件");
                            }

                            @Override
                            public void onComplete() {
                                Log.e("TAG", "接收到了onComplete事件");
                            }
                        });

log打印結果:下圖可知,不適用concatDelayonError時,事件4、5、6沒有被發射出來,而使用concatDelayonError時,會發射玩所有事件后,在發射onError事件,就是onError事件被延遲發射了,此情況mergeDelayError雷同,代碼就省略了

image.png

4.5 合并多個事件Zip()的簡單使用

① 該類型的操作符主要是對多個被觀察者中的事件進行合并處理
② 合并 多個被觀察者(Observable)發送的事件,生成一個新的事件序列(即組合過后的事件序列),并最終發送
③ 事件組合方式 = 嚴格按照原先事件序列 進行對位合并
④ 最終合并的事件數量 = 多個被觀察者(Observable)中數量最少的數量

//創建第1個被觀察者
        Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                Log.e("TAG", "可觀察者1發送了事件 1");
                emitter.onNext(1);
                // 為了方便展示效果,所以在發送事件后加入2s的延遲
                Thread.sleep(2000);

                Log.e("TAG", "可觀察者1發送了事件2");
                emitter.onNext(2);
                Thread.sleep(2000);

                Log.e("TAG", "可觀察者1發送了事件3");
                emitter.onNext(3);
                Thread.sleep(2000);

                Log.e("TAG", "可觀察者1發送了事件4");
                emitter.onNext(4);
                Thread.sleep(2000);

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io()); // 設置可觀察者1    在線程1中執行


        //創建第2個可觀察者
        Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.e("TAG", "可觀察者 2 發送了事件 A ");
                emitter.onNext("A");
                Thread.sleep(2000);

                Log.e("TAG", "可觀察者 2 發送了事件 B ");
                emitter.onNext("B");
                Thread.sleep(2000);

                Log.e("TAG", "可觀察者 2 發送了事件 C ");
                emitter.onNext("C");
                Thread.sleep(2000);

                Log.e("TAG", "可觀察者 2 發送了事件 D ");
                emitter.onNext("D");
                Thread.sleep(2000);

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.newThread());// 設置可觀察者 2    在 線程2中執行
        // 假設不作線程控制,則該兩個被觀察者會在同一個線程中工作,即發送事件存在先后順序,而不是同時發送

        // 使用zip變換操作符進行事件合并
        // 注:創建BiFunction對象傳入的3個參數 ==可觀察者1的數據類型  可觀察者2的數據類型   合并后數據的數據類型
        Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer integer, String string) throws Exception {
                return integer + string;
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e("TAG", "onSubscribe");
            }

            @Override
            public void onNext(String value) {
                Log.e("TAG", "最終接收到的事件 =  " + value);
            }

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

            @Override
            public void onComplete() {
                Log.e("TAG", "onComplete");
            }
        });

log打印結果:

1525422593(1).jpg

4.6 combineLatest()的簡單使用

① 當兩個Observables中的任何一個發送了數據后,將先發送了數據的Observables 的最新(最后)一個數據 與 另外一個Observable發送的每個數據結合,最終基于該函數的結果發送數據
② 與Zip()的區別:Zip() = 按個數合并,即1對1合并;CombineLatest() = 按時間合并,即在同一個時間點上合并

Observable.combineLatest(
                Observable.just(1L, 2L, 3L), // 第1個發送數據事件的Observable
                Observable.intervalRange(0, 3, 2, 2, TimeUnit.SECONDS), // 第2個發送數據事件的Observable:從0開始發送、共發送3個數據、第1次事件延遲發送時間 = 2s、間隔時間 = 2s
                new BiFunction<Long, Long, Long>() {
                    @Override
                    public Long apply(Long o1, Long o2) throws Exception {
                        // o1 = 第1個Observable發送的最新(最后)1個數據
                        // o2 = 第2個Observable發送的每1個數據
                        Log.e("TAG", "合并的數據是: "+ "第一個  "+o1 + " "+ "第二個  "+o2);
                        return o1 + o2;
                        // 合并的邏輯 = 相加
                        // 即第1個Observable發送的最后1個數據 與 第2個Observable發送的每1個數據進行相加
                    }
                }).subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long s) throws Exception {
                Log.e("TAG", "合并的結果是: "+s);
            }
        });

log打印結果:

image.png

4.6 collect()的簡單使用

① 將被觀察者Observable發送的數據事件收集到一個數據結構里

Observable.just(1, 2, 3 ,4, 5, 6)
                .collect(
                        // 1. 創建數據結構(容器),用于收集被觀察者發送的數據
                        new Callable<ArrayList<Integer>>() {
                            @Override
                            public ArrayList<Integer> call() throws Exception {
                                return new ArrayList<>();
                            }
                            // 2. 對發送的數據進行收集
                        }, new BiConsumer<ArrayList<Integer>, Integer>() {
                            @Override
                            public void accept(ArrayList<Integer> list, Integer integer)
                                    throws Exception {
                                // 參數說明:list = 容器,integer = 后者數據
                                list.add(integer);
                                // 對發送的數據進行收集
                            }
                        }).subscribe(new Consumer<ArrayList<Integer>>() {
            @Override
            public void accept(@NonNull ArrayList<Integer> s) throws Exception {
                Log.e("TAG", "本次發送的數據是: "+s);

            }
        });

log打印結果:

image.png

4.7、startWith() / startWithArray()發送事件前追加發送事件

① 在一個被觀察者發送事件前,追加發送一些數據 / 一個新的被觀察者

 //在一個被觀察者發送事件前,追加發送一些數據
        // 注:追加數據順序 = 后調用先追加
        Observable.just(4, 5, 6)
                .startWithArray(1, 2, 3) // 追加多個數據 = startWithArray()
                .startWith(0)  // 追加單個數據 = startWith()
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.e("TAG", "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "對Error事件作出響應");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "對Complete事件作出響應");
                    }
                });


        // 在一個被觀察者發送事件前,追加發送被觀察者 & 發送數據
        // 注:追加數據順序 = 后調用先追加
        Observable.just(4, 5, 6)
                .startWith(Observable.just(1, 2, 3))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.e("TAG", "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "對Error事件作出響應");
                    }

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "對Complete事件作出響應");
                    }
                });

log打印結果:

image.png

4.8、count()統計發送事件數量

① 統計被觀察者發送事件的數量

// 注:返回結果 = Long類型
        Observable.just(1, 2, 3, 4)
                .count()
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.e("TAG", "發送的事件數量 =  "+aLong);

                    }
                });

log打印結果:

image.png

4.10、組合 / 合并操作符 總結

圖片來自:http://www.lxweimin.com/p/c2a7c03da16d

5、RxJava的線程控制(切換 / 調度 ):異步操作

① 指定 可觀察者 (Observable) / 觀察者(Observer) 的工作線程類型
② 線程控制(也稱為調度 / 切換)功能性操作符中的:subscribeOn() 與 observeOn()
Observable.subscribeOn(Schedulers.Thread):指定被觀察者 發送事件的線程(傳入RxJava內置的線程類型)
Observable.observeOn(Schedulers.Thread):指定觀察者 接收 & 響應事件的線程(傳入RxJava內置的線程類型)
subscribeOn(Schedulers.newThread()) :指定被觀察者 生產事件的線程
observeOn(AndroidSchedulers.mainThread()) :指定觀察者 接收 & 響應事件的線程

5.1 指定可觀察者 發射線程 subscribeOn()

若Observable.subscribeOn()多次指定可觀察者 生產事件的線程,則只有第一次指定有效,其余的指定線程無效

observable.subscribeOn(Schedulers.newThread()) // 第一次指定被觀察者線程 = 新線程
                .subscribeOn(AndroidSchedulers.mainThread()) // 第二次指定被觀察者線程 = 主線程
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);

//被觀察者的線程 = 第一次指定的線程 = 新的工作線程,第二次指定的線程(主線程)無效

5.2 指定觀察者 接收線程 subscribeOn()

若Observable.observeOn()多次指定觀察者 接收 & 響應事件的線程,則每次指定均有效,即每調用一次observeOn(),觀察者的線程就會切換一次

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {

            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread()) // 第一次指定觀察者線程 = 主線程
                .doOnNext(new Consumer<String>() { // 生產事件
                    @Override
                    public void accept(String string) throws Exception {
                        Log.d("TAG", "第一次觀察者Observer的工作線程是: " + Thread.currentThread().getName());
                    }
                })
                .observeOn(Schedulers.newThread()) // 第二次指定觀察者線程 = 新的工作線程
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        
                    }
                }); // 生產事件


        // 注:
        // 1. 整體方法調用順序:觀察者.onSubscribe()> 被觀察者.subscribe()> 觀察者.doOnNext()>觀察者.onNext()>觀察者.onComplete() 
        // 2. 觀察者.onSubscribe()固定在主線程進行

log打印結果:

5.3、背壓策略詳情請看--關于 RxJava 最友好的文章系列

被觀察者發送事件速度遠快于觀察者的處理速度的情況下,一種告訴上游的被觀察者降低發送速度的策略

 // 步驟1:創建被觀察者 =  Flowable
        Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                Log.e("TAG", "發送事件 1");
                emitter.onNext(1);
                Log.e("TAG", "發送事件 2");
                emitter.onNext(2);
                Log.e("TAG", "發送事件 3");
                emitter.onNext(3);
                Log.e("TAG", "發送完成");
                emitter.onComplete();
            }
        }, BackpressureStrategy.ERROR)
                .subscribe(new Subscriber<Integer>() {
                    // 步驟2:創建觀察者 =  Subscriber & 建立訂閱關系

                    @Override
                    public void onSubscribe(Subscription s) {
                        Log.e("TAG", "onSubscribe");
                        s.request(3);
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.e("TAG", "接收到了事件" + integer);
                    }

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

                    @Override
                    public void onComplete() {
                        Log.e("TAG", "onComplete");
                    }
                });

6、錯誤處理 使用代碼示例與詳細講解

發送事件過程中,遇到錯誤時的處理機制,
網絡請求失敗,加載本地,重試等

操作符有

1、 onErrorReturn(): 遇到錯誤時,發送1個特殊事件 & 正常終止
①、可捕獲在它之前發生的異常

2、 onErrorResumeNext(): 遇到錯誤時,發送1個新的Observable
①、onErrorResumeNext()攔截的錯誤 = Throwable;若需攔截Exception請用onExceptionResumeNext()
②、若onErrorResumeNext()攔截的錯誤 = Exception,則會將錯誤傳遞給觀察者的onError方法

3、onExceptionResumeNext():遇到錯誤時,發送1個新的Observable
①、onExceptionResumeNext()攔截的錯誤 =Exception;若需攔截Throwable請用onErrorResumeNext()
②、若onExceptionResumeNext()攔截的錯誤 = Throwable,則會將錯誤傳遞給觀察者的onError方法

4、retry(): 重試,即當出現錯誤時,讓被觀察者(Observable)重新發射數據
①、接收到onError()時,重新訂閱 & 發送事件
②、ThrowableException都可攔截

5、retryUntil(): 出現錯誤后,判斷是否需要重新發送數據
①、若需要重新發送 & 持續遇到錯誤,則持續重試
②、作用類似于retry(Predicate predicate)
③、具體場景:類似于retry(Predicate predicate),唯一區別:返回 true 則不重新發送數據事件。

6、retryWhen(): 重試,即當出現錯誤時,讓被觀察者(Observable)重新發射數據
①、接收到 onError()時,重新訂閱 & 發送事件
②、ThrowableException都可攔截

7、retryWhen(): 遇到錯誤時,將發生的錯誤傳遞給一個新的被觀察者(Observable),并決定是否需要重新訂閱原始被觀察者(Observable)& 發送事件

7、重復發送 使用代碼示例與詳細講解

重復不斷地發送被觀察者事件
對應操作符類型:repeat() &repeatWhen()

1、repeat(): 無條件地、重復發送 被觀察者事件
①、具備重載方法,可設置重復創建次數

2、repeatWhen(): 有條件地、重復發送 被觀察者事件

①、將原始 Observable 停止發送事件的標識(Complete() / Error())轉換成1個 Object類型數據傳遞給1個新被觀察者(Observable),以此決定是否重新訂閱 & 發送原來的 Observable
②、若新被觀察者(Observable)返回1個Complete / Error事件,則不重新訂閱 & 發送原來的 Observable
③、若新被觀察者(Observable)返回其余事件時,則重新訂閱 & 發送原來的 Observable

8、composeTransformer 消除重復代碼

詳細講解看 1 2 3 這三篇文章

8.1、在使用RXJava與Retrofit請求網絡時,遇到過這樣的場景,在IO線程請求網絡解析數據,接著返回主線程setData、更新View試圖,代碼如下:

.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);

8.2、這樣肯定是沒問題的,但是如果請求網絡的次數多了,豈不是每個地方都要寫一遍?,并且同時又不想去破環RX的鏈式結構,怎么辦呢,有一個不是唯一的辦法,就是使用操作符

RetrofitClient.getData("網絡接口URL")
.requestNetData("參數1","參數2")
.compose(CommonTransformer())//自定義ObservableTransformer,完成線程切換
.subscribe(subscriber);

就是用 .compose(schedulersTransformer()) 這一行一行代碼就完成了線程切換,代替了.subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())這段代碼

8.3、實現ObservableTransformer,完成線程切換,然后使用compose()操作符

/**
 * ================================================
 * Created by ${chenyuexueer}
 * 說明:實現ObservableTransformer,完成線程切換,使用compose()操作符
 * ================================================
 */
Observable.Transformer schedulersTransformer() {
        return new Observable.Transformer() {
            @Override
            public Object call(Object observable) {
                return ((Observable)  observable).subscribeOn(Schedulers.io())
                        .unsubscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread());
            }
        };
    }
//一行代碼搞定,使用情況如下:
//observable.compose (schedulersTransformer()).subscribe(subscriber)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 我從去年開始使用 RxJava ,到現在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy閱讀 5,570評論 7 62
  • 轉一篇文章 原地址:http://gank.io/post/560e15be2dca930e00da1083 前言...
    jack_hong閱讀 947評論 0 2
  • 前言我從去年開始使用 RxJava ,到現在一年多了。今年加入了 Flipboard 后,看到 Flipboard...
    占導zqq閱讀 9,203評論 6 151
  • 最近項目里面有用到Rxjava框架,感覺很強大的巨作,所以在網上搜了很多相關文章,發現一片文章很不錯,今天把這篇文...
    Scus閱讀 6,900評論 2 50
  • 刪除
    帥小冰閱讀 590評論 1 4