RxJava學習指南

目錄

基礎用法

線程調度

關鍵字

create

map

flatMap/concatMap

timer

interval

zip

concat/merge

distinct

filter

buffer

skip/skipLast

take/takeLast

single

debounce/ThrottleWithTimeout

last

reduce/scan


RxJava github

RxAndroid github

RxJava翻譯

基礎用法

使用步驟:

  1. 初始化 Observable
  2. 初始化 Observer
  3. 訂閱

當然不要忘了根據github地址添加依賴。

    private static Observable<Integer> getObservable() {
        return Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {

                Log.i(TAG, "subscribe:  發送 1 " + Thread.currentThread().getName());
                observableEmitter.onNext(1);

                Log.i(TAG, "subscribe:  發送 2 " + Thread.currentThread().getName());
                observableEmitter.onNext(2);

                Log.i(TAG, "subscribe:  發送 3 " + Thread.currentThread().getName());
                observableEmitter.onNext(3);

                Log.i(TAG, "subscribe:  發送 4 " + Thread.currentThread().getName());
                observableEmitter.onNext(4);
            }
        });
    }

    public static void step1() {
        // 1.初始化Obervable
        Observable<Integer> observable = getObservable();

        // 2.初始化Observer
        Observer<Integer> observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable disposable) {
                mDisposable = disposable;
            }

            @Override
            public void onNext(Integer integer) {
                Log.i(TAG, "onNext: 接收數據" + integer);

                if (integer == 3) {
                    Log.i(TAG, "onNext: 主動銷燬數據" + integer);
                    mDisposable.dispose();
                }
            }

            @Override
            public void onError(Throwable throwable) {
                Log.i(TAG, "onError: 錯誤數據" + throwable.getMessage());
            }

            @Override
            public void onComplete() {
                Log.i(TAG, "onComplete: 完成");
            }
        };

        // 3.創建訂閱關係
        observable.subscribe(observer);
    }

線程調度

subscribeOn:指定被訂閱數據線程,即發送數據上游線程。多次調用僅第一次有效。

observeOn:指定觀察者線程,即接收數據下游線程。多次調用多次生效,根據最近一次調用調度線程。

public static void scheduler() {
        Observable<Integer> observable = getObservable();
        observable
                .subscribeOn(AndroidSchedulers.mainThread()) // 主線程發射數據
                .subscribeOn(Schedulers.newThread()) // 子線程發射數據
                .subscribeOn(Schedulers.io()) // io線程發射數據
                .observeOn(AndroidSchedulers.mainThread()) // 主線程接收數據
                .doOnNext(new Consumer<Integer>() { // 在accept之前調用
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept: AndroidSchedulers.mainThread() 當前線程" + Thread.currentThread().getName());
                        Log.i(TAG, "accept: AndroidSchedulers.mainThread() 接收數據" + integer);
                    }
                })
                .observeOn(Schedulers.io()) // io線程接收數據
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept: AndroidSchedulers.io() 當前線程" + Thread.currentThread().getName());
                        Log.i(TAG, "accept: AndroidSchedulers.io() 接收數據" + integer);
                    }
                });
    }
doOnNext:在下游接收數據前調用。onNext()之前。
doAfterNext:在接收數據之後調用。onNext()之後。

關鍵字

 

create

產生一個 Obserable 被觀察者對象,即上游發射器。

 

map

將發射出來的數據一一映射處理一遍。

public static void map() {
        Observable<Integer> observable = getObservable();
        // 將 int --> String
        observable.map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Exception {
                return "map " + integer;
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: ==" + s);
            }
        });
    }

 

flatMap/concatMap

將一組上游發射數據轉換爲N個Observable,之後無序/有序的發射這N個發射器的數據。

    public static void flatMap() {
        getIntObservable()
                .flatMap(new Function<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Integer integer) throws Exception {
                        ArrayList<String> list = new ArrayList<>();
                        for (int i = 0; i < integer; i++) {
                            list.add("第" + integer + "波數據:" + i);
                        }
                        return Observable.fromIterable(list).delay(3-integer, TimeUnit.SECONDS);
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: 接收數據 " + s);
            }
        });
    }

 

timer

定時任務。訂閱後延時多久開始發射數據。

    public static void timer() {
        final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Log.i(TAG, "timer: 開始時間 " + dateFormat.format(System.currentTimeMillis()));
        Observable.timer(2,TimeUnit.SECONDS)
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.i(TAG, "timer: 結束時間 " + dateFormat.format(System.currentTimeMillis()));
                    }
                });
    }

 

interval

計時任務。每隔一段時間發射一次數據。

延遲1s後開始計時,每次間隔1s,5s後標記任務爲處理狀態。

    public static void interval() {
        final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Log.i(TAG, "timer: 開始時間 " + dateFormat.format(System.currentTimeMillis()));
        Disposable disposable = Observable.interval(1, 1, TimeUnit.SECONDS)
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.i(TAG, "timer: 計時 " + dateFormat.format(System.currentTimeMillis()));
                    }
                });
        try {
            Thread.sleep(5000);
            disposable.dispose();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

 

zip

將兩個或以上發射器數據合併在一起,按一一對應方式合併,所以最終結果是按照最小數量發射器,多的數據直接捨棄。從下例可以看出結果只能到 " three is 3" ,"four" 被捨棄了。

    public static void zip() {
        Observable.zip(getIntObservable(), getStringObservable(),
                new BiFunction<Integer, String, String>() {
                    @Override
                    public String apply(Integer integer, String s) throws Exception {
                        return s + " is " + integer;
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: " + s);
            }
        });
    }
private static Observable<Integer> getIntObservable() {
        return Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {

//                Log.i(TAG, "subscribe:  發送 1 " + Thread.currentThread().getName());
                observableEmitter.onNext(1);

//                Log.i(TAG, "subscribe:  發送 2 " + Thread.currentThread().getName());
                observableEmitter.onNext(2);

//                Log.i(TAG, "subscribe:  發送 3 " + Thread.currentThread().getName());
                observableEmitter.onNext(3);

                // 通知下游數據發送完成 後續數據不在接收
                observableEmitter.onComplete();

//                Log.i(TAG, "subscribe:  發送 4 " + Thread.currentThread().getName());
                observableEmitter.onNext(4);
            }
        });
    }

    private static Observable<String> getStringObservable() {
        return Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {

                observableEmitter.onNext("one");

                observableEmitter.onNext("two");

                observableEmitter.onNext("three");

                observableEmitter.onNext("four");

                // 通知下游數據發送完成 後續數據不在接收
                observableEmitter.onComplete();
            }
        });
    }

 

concat/merge

將兩個上游發射器合併在一起,按照順序依次發送數據/無序發送數據。合併的observable的數據類型必須相同。

    public static void concat(){
        Observable.concat(getIntObservable(),getIntObservable())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept: " + integer);
                    }
                });
    }

從結果可以看concat出是在第一個observable之後有序發射第二個observable的數據。

 

distinct

去重,去除重複的數據。

class DistinctBean {

    String name;
    int id;

    public DistinctBean(String name, int id) {
        this.name = name;
        this.id = id;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof DistinctBean)) return false;
        DistinctBean that = (DistinctBean) o;
        return id == that.id &&
                Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, id);
    }
}
    private static Observable<DistinctBean> getDistinctObservable() {
        return Observable.create(new ObservableOnSubscribe<DistinctBean>() {
            @Override
            public void subscribe(ObservableEmitter<DistinctBean> observableEmitter) throws Exception {

                observableEmitter.onNext(new DistinctBean("a", 1));

                observableEmitter.onNext(new DistinctBean("b", 1));

                observableEmitter.onNext(new DistinctBean("b", 1));

                observableEmitter.onNext(new DistinctBean("b", 2));

                // 通知下游數據發送完成 後續數據不在接收
                observableEmitter.onComplete();
            }
        });
    }

1.不指定key,直接進行對象比較,過濾掉一個數據 {b,1}

        getDistinctObservable().distinct()
                .subscribe(new Consumer<DistinctBean>() {
                    @Override
                    public void accept(DistinctBean distinctBean) throws Exception {
                        Log.i(TAG, "accept:   " + distinctBean.toString());
                    }
                });

2.指定比較的key是name字段,過濾掉後兩個數據

        getDistinctObservable().distinct(new Function<DistinctBean, String>() {
            @Override
            public String apply(DistinctBean distinctBean) throws Exception {
                return distinctBean.name;
            }
        }).subscribe(new Consumer<DistinctBean>() {
            @Override
            public void accept(DistinctBean distinctBean) throws Exception {
                Log.i(TAG, "accept:   " + distinctBean.toString());
            }
        });

 

filter

根據條件過濾掉無用數據。

    public static void filter(){
        getDistinctObservable().filter(new Predicate<DistinctBean>() {
            @Override
            public boolean test(DistinctBean distinctBean) throws Exception {
                // true 通過篩選
                return "b".equals(distinctBean.name);
            }
        }).subscribe(new Consumer<DistinctBean>() {
            @Override
            public void accept(DistinctBean distinctBean) throws Exception {
                Log.i(TAG, "accept: " + distinctBean.toString());
            }
        });
    }

 

buffer

分組截取,將上游發射器數據分組,新的發射器每次發射一組數據。

下例,每次遊標滑動4,然後取後面的3個數爲一個List發射。

結果爲:[1,2,3] [5,6,7]

    public static void buffer() {
        Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
                .buffer(3, 4)
                .subscribe(new Consumer<List<Integer>>() {
                    @Override
                    public void accept(List<Integer> integers) throws Exception {
                        Log.i(TAG, "accept: " + integers.toString());
                    }
                });
    }

 

skip/skipLast

捨棄一些數據後開始接收數據。從前/從後

    public static void skip(){
        Observable.just(1,2,3,4,5)
                .skipLast(2)
//                .skip(2)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept:  " + integer);
                    }
                });
    }

 

take/takeLast

只接收一定量的數據。從前/從後

    public static void take(){
        Observable.just(1,2,3,4,5,6)
                .take(2)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept:  " + integer); // 結果 1 2
                    }
                });
    }

 

single

單個數據發射器。SingleObserver只回調onSuccess和onError。

   public static void single(){
        Single.just(1)
                .subscribe(new SingleObserver<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onSuccess(Integer integer) {
                        Log.i(TAG, "onSuccess: " + integer);
                    }

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

 

debounce/ThrottleWithTimeout

去抖動,覆蓋掉間隔過短的數據,即有效數據爲短間隔的後一個數據。

   public static void debounce() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1); // 被覆蓋
                Thread.sleep(200);
                emitter.onNext(2); // 接收
                Thread.sleep(600);
                emitter.onNext(3); // 被覆蓋
                Thread.sleep(300);
                emitter.onNext(4); // 被覆蓋
                Thread.sleep(300);
                emitter.onNext(5); // 接收
            }
        }).throttleWithTimeout(400, TimeUnit.MILLISECONDS)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept: " + integer); // 結果 2 5
                    }
                });
    }

 

last

只接收最後一個數據,當沒有數據時,發射傳入的默認值。

    public static void last() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onComplete();
            }
        }).last(3)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "accept: " + integer); // 結果 3
                    }
                });
    }

 

reduce/scan

將數據按照方法依次兩兩操作,可以設置一個初始值。

reduce只關注結果的一次數據。

scan每一步的數據都發射一次。seed也會發射一次。

    public static void reduce(){
        Observable.just(1,2,3,4)
                .reduce(2, new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer, Integer integer2) throws Exception {
                        return integer + integer2;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.i(TAG, "accept: " + integer); // 結果 12   scan結果:2 3 5 8 12
            }
        });
    }

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章