RxJava 1.x 理解-3

在 RxJava 1.x 理解-1 中,咱們說到了RxJava的簡單用法,可是這還遠遠不夠,由於html

輸入的數據 ---> 被監聽者(訂閱源)對這些數據進行操做,或者執行響應的處理 --> 產生新的數據,或者事件發送給監聽者 --> 監聽者執行本身的方法。java

其中,RxJava還能夠對輸入的數據進行變換,產生新數據(能夠是複雜的數據),而不是簡單的事件觸發。數組

先將數據的提供,進階一下:

rxJava just 使用

    /**
     * rxJava just 使用
     * just --> 仍是使用的create方法
     */
    private void rxJavaJust() {
        Log.d(TAG, "----------- just ---------");

        Observable
                .just("just 1", "just 2", "just 3")
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d(TAG, "Item: " + s);
                    }
                });
    }

just會不斷的將可變參數數據 just 1 ;just 2 ;just 3 .... 發送出去ide

rxJava from 使用

    /**
     * rxJava from 使用
     * from --> 仍是使用的create方法
     */
    private void rxJavaFrom() {
        Log.d(TAG, "----------- from ---------");

        String[] names = {"1", "2", "3"};
        Observable.from(names)
                .subscribe(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!");
                    }
                });

        Log.d(TAG, "----------- from2 ---------");

        // 簡單來講就是數據提供了,並且是一個個的提供了,至於要如何執行,那就按觀察者本身的事情了。
        Observable.from(names)
                .subscribe(new Action1<String>() {

                    @Override
                    public void call(String s) {
                        Log.d(TAG, "Item: " + s);
                    }

                });
    }

from會不斷的將數組或者集合中的數據一個個發送出去post

數據變換

rxjava map 變換

    /**
     * rxjava map 變換
     * 將類型轉化成另外一個類型
     */
    private void rxJavaMap() {
        Log.d(TAG, "----------- Map ---------");

        Observable.just("1") // 輸入類型 String
                .map(new Func1<String, Integer>() {
                    @Override
                    public Integer call(String s) {
                        return Integer.parseInt(s);
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.d(TAG, "Item: " + integer + " 執行調用 獲取線程id:" + Thread.currentThread().getId());
                    }
                });
    }
        Observable.just("999", "11") // 輸入類型 String
                .map(new Func1<String, List<Integer>>() {
                    @Override
                    public List<Integer> call(String s) {
                        List<Integer> ints = new ArrayList<>();
                        ints.add(Integer.parseInt(s));
                        ints.add(Integer.parseInt(s));
                        ints.add(Integer.parseInt(s));
                        return ints;
                    }
                }).subscribe(new Action1<List<Integer>>() {
            @Override
            public void call(List<Integer> integers) {
                int i = 0;
                // 這裏進行遍歷
                for (Integer integer : integers) {
                    Log.e(TAG, "Item " + i + " :" + +integer);
                    i += 1;
                }
            }
        });

    }

能夠看到,將String格式的數據轉換成了Integer格式的數據,或者是String格式的數據轉換成List<Integer>格式的數據。map是一對一的變換。測試

rxjava flatMap 變換

    /**
     * rxjava flatMap 變換
     * 事件再次分發:
     *
     * 從上面的代碼能夠看出, flatMap() 和 map() 有一個相同點:它也是把傳入的參數轉化以後返回另外一個對象。
     * 但須要注意,和 map() 不一樣的是, flatMap() 中返回的是個 Observable 對象,但這個 Observable 對象並非被直接發送到了 Subscriber 的回調方法中。
     * flatMap() 的原理是這樣的:
     * 1. 使用傳入的事件對象建立一個 Observable 對象;
     * 2. 並不發送這個 Observable, 而是將它激活,因而它開始發送事件;
     * 3. 每個建立出來的 Observable 發送的事件,都被匯入同一個 Observable ,而這個 Observable 負責將這些事件統一交給 Subscriber 的回調方法。
     * 這三個步驟,把事件拆成了兩級,經過一組新建立的 Observable 將初始的對象『鋪平』以後經過統一路徑分發了下去。而這個『鋪平』就是 flatMap() 所謂的 flat。
     */
    private void rxJavaFlatMap() {
        Log.d(TAG, "----------- rxJavaFlatMap ---------");

        List<Student> students = new ArrayList<>();
        List<Source> sources = new ArrayList<>();
        sources.add(new Source(1, "化學", 80));
        sources.add(new Source(2, "物理", 79));
        sources.add(new Source(3, "生物", 78));
        students.add(new Student("小明1", 1, sources));
        students.add(new Student("小明2", 1, sources));
        Observable.from(students)
                .flatMap(new Func1<Student, Observable<Source>>() {
                    @Override
                    public Observable<Source> call(Student student) {
                        Log.d(TAG, "Item: " + student.name);
                        return Observable.from(student.mSources);
                    }
                })
                .subscribe(new Action1<Source>() {
                    @Override
                    public void call(Source source) {
                        Log.d(TAG, "Item: " + source + " 執行調用 獲取線程id:" + Thread.currentThread().getId());
                    }
                });
    }
 // ------------------------ 測試使用的類 -----------------------------

    class Student {
        String name;//學生名字
        int id;
        List<Source> mSources;//每一個學生的全部課程

        public Student(String name, int id, List<Source> sources) {
            this.name = name;
            this.id = id;
            mSources = sources;
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", id=" + id +
                    ", mSources=" + mSources +
                    '}';
        }
    }

    class Source {
        int sourceId;//id
        String name;//課程名
        int score;//成績

        public Source(int sourceId, String name, int score) {
            this.sourceId = sourceId;
            this.name = name;
            this.score = score;
        }

        @Override
        public String toString() {
            return "Source{" +
                    "sourceId=" + sourceId +
                    ", name='" + name + '\'' +
                    ", score=" + score +
                    '}';
        }
    }

輸出結果:this

02-09 15:45:50.580 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: 小明1
02-09 15:45:50.581 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=1, name='化學', score=80} 執行調用 獲取線程id:2
02-09 15:45:50.581 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=2, name='物理', score=79} 執行調用 獲取線程id:2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=3, name='生物', score=78} 執行調用 獲取線程id:2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: 小明2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=1, name='化學', score=80} 執行調用 獲取線程id:2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=2, name='物理', score=79} 執行調用 獲取線程id:2
02-09 15:45:50.583 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=3, name='生物', score=78} 執行調用 獲取線程id:2

 其實上述代碼,也能夠用map實現:url

        Observable.from(students).map(new Func1<Student, List<Source>>() {
            @Override
            public List<Source> call(Student student) {
                Log.d(TAG, "Item: " + student.name);
                return student.mSources;
            }
        }).subscribe(new Action1<List<Source>>() {
            @Override
            public void call(List<Source> sources) {
                // 主要的差距是這裏,咱們本身進行了一次循環遍歷。而flatMap則不用,直接獲取到的就是Source對象,而不是List<Source>對象
                for (Source source:sources){
                    Log.d(TAG, "Item: " + source + " 執行調用 獲取線程id:" + Thread.currentThread().getId());
                }
            }
        });
從上面的代碼能夠看出, 
flatMap() 和 map() 有一個相同點:它也是把傳入的參數轉化以後返回另外一個對象。
但須要注意,和 map() 不一樣的是, flatMap() 中返回的是個 Observable 對象,但這個 Observable 對象並非被直接發送到了 Subscriber 的回調方法中。
flatMap() 的原理是這樣的:
1. 使用傳入的事件對象建立一個 Observable 對象;
2. 並不發送這個 Observable, 而是將它激活,因而它開始發送事件;
3. 每個建立出來的 Observable 發送的事件,都被匯入同一個 Observable ,而這個 Observable 負責將這些事件統一交給 Subscriber 的回調方法。
這三個步驟,把事件拆成了兩級,經過一組新建立的 Observable 將初始的對象『鋪平』以後經過統一路徑分發了下去。而這個『鋪平』就是 flatMap() 所謂的 flat。

總結:RxJava的做用就是
對於數據:對輸入的數據進行變換,轉換成想要的數據,而且能夠指定執行的線程,獲得最終的結果。
對於事件:觸發事件,觀察者感知,觀察者執行操做,而且能夠指定執行的線程。

參考資料:spa

一塊兒來造一個RxJava,揭祕RxJava的實現原理.net

給 Android 開發者的 RxJava 詳解

相關文章
相關標籤/搜索