Rxjava2操作符入門(一)

android大哥發表於2017-12-08

友情連結:
Rxjava2操作符(一)
Rxjava2操作符(二)
Rxjava2操作符(三)
demo地址:github

1. 概述:

用官網的一句話:"a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成非同步的、基於事件的程式的庫)。這就是 RxJava ,概括得非常精準。也就是我們們常說的鏈式程式設計

2. Rxjava的好處

非同步操作很關鍵的一點是程式的簡潔性,因為在排程過程比較複雜的情況下,非同步程式碼經常會既難寫也難被讀懂。 Android 創造的 AsyncTask 和Handler ,其實都是為了讓非同步程式碼更加簡潔。RxJava的優勢也是簡潔,但它的簡潔的與眾不同之處在於,隨著程式邏輯變得越來越複雜,它依然能夠保持簡潔(本段內容摘自扔物線的部落格)。

3. 觀察者和被觀察者

  • Observable(被觀察者)/Observer(觀察者) Obsesrver用來連線這兩個
  • Flowable(被觀察者)/Subscriber(觀察者) (2.0出現的支援背壓) subscribe用來連線這兩個

4. 簡單使用

發射源有多少個onNext就會發射多少次,onComplete 和 onError是衝突的兩個方法,有你沒我,有我沒你 如果在onComplete或者onError呼叫OnNext方法不會再起作用

    //建立被觀察者
    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onComplete();
                e.onNext(3);
                //e.onError(new Throwable());
            }
        });
        //建立觀察者
        Observer<Integer> observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.i(TAG,"onSubscribe訂閱了");
            }

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

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

            @Override
            public void onComplete() {
                Log.i(TAG,"onComplete");
            }
        };
        // 開始訂閱
        observable.subscribe(observer);
複製程式碼

列印出來的Log為

onSubscribe訂閱了
onNext1
onNext2
onComplete
複製程式碼

4.1 Observer(觀察者)中的方法

  • onSubscribe(Disposable d)
    當訂閱到被觀察者的時候呼叫 , Disposable 用來解除訂閱的,防止記憶體洩漏
  • onNext(T t)
    被觀察者傳送OnNext方法的時候呼叫
  • onComplete()
    當被觀察者呼叫onComplete方法時執行
  • onError(Throwable e)
    當被觀察者呼叫onError方法時執行

subscribe()方法內可以傳遞的東西

  • Consumer<? super T> onNext
    表示被觀察者只關注onNext
  • Consumer<? super T> onNext, Consumer<? super Throwable> onError)
    表示被觀察者只關注onNext 和 onError
  • Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete)
    表示被觀察者只關注onNext 和 onError 和 onComplete
  • Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe)
    表示被觀察者四個方法都關注

5. 大致的操作符分為以下幾點:

當然了下面的也不是所有的操作符

建立型 Create Just fromIterable Timer Interval Repeat
轉化型 Map FlatMap Buffer Scan Window GroupBy
過濾型 Filter Distince Skip Take Last Debounce
組合型 Zip Join And Switch Merge StartWith
錯誤處理性 Retry Catch
輔助型 SubscribeOn ObserveOn Timer Interval DoOnNext Delay
條件和布林 All SkipUntil TakeUntil Contains Amb
算數和聚合型 Conact Count Max Min Sum
連線型 Connect Publish Replay RefCount
非同步操作 Start ToAsync StartFuture FromAction FromCallable RunAsync
阻塞操作 ForEach Firsh Last MostRecent Next Single
字串操作 Split Decode Encode Join Form ByLine

6. 建立型(Creating): 也就是建立 Observable (被觀察者)

6.1 Create (表示只傳送OnNext方法)

    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
        }
    }).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            Log.i(TAG,integer+"");
        }
    });
複製程式碼

列印出來

12-12 05:17:00.307 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 1
12-12 05:17:00.307 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 2
12-12 05:17:00.307 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 3
複製程式碼

6.2 just (將傳入的引數依次傳送出來)

    Observable.just(1,2,3).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            Log.i(TAG,integer+"");
        }
    });
複製程式碼

列印出來

12-12 05:17:32.349 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 1
12-12 05:17:32.349 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 2
12-12 05:17:32.349 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 3
複製程式碼

6.3 fromIterable (將Iterable中的物件依次傳送出去)

同樣 fromArray 是將 陣列 中的資料依次傳送出去

    ArrayList<String >  arrayList = new ArrayList<>();
    for(int i = 0;i<3;i++) {
        arrayList.add(""+i+i);
    }
    Observable.fromIterable(arrayList).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.i(TAG,s+"");
        }
    });
複製程式碼

列印出來

12-12 05:17:46.458 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 00
12-12 05:17:46.458 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 11
12-12 05:17:46.458 19635-19635/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 22
複製程式碼

6.4 Timer (它在一個給定的延遲後發射一個特殊的值,等同於Android中Handler的postDelay( )方法)

//                        DAYS,HOURS,MICROSECONDS,MILLISECONDS,MINUTES,NANOSECONDS,SECONDS;
//                        天   小時   微秒         毫秒         分鐘    納秒       秒                             
   final long start = System.currentTimeMillis();
                Observable.timer(1000, TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        long end = System.currentTimeMillis();
                        Log.i(TAG,"時間差:"+(end-start)+"ms");
                    }
                });
複製程式碼

列印出來

12-12 05:20:22.483 20471-20629/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 時間差:1008ms
複製程式碼

6.5 Interval (建立一個按固定時間間隔發射整數序列)

可以用來當做計時器,或者間隔性請求網路資料

 Observable.interval(1000, TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                         Log.i(TAG,""+aLong);
                    }
                });
複製程式碼

列印出來

12-12 05:25:35.379 21915-21971/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 0
12-12 05:25:36.379 21915-21971/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 1
12-12 05:25:37.379 21915-21971/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 2
12-12 05:25:38.379 21915-21971/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 3
12-12 05:25:39.379 21915-21971/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 4
12-12 05:25:40.379 21915-21971/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 5
...
...
...
複製程式碼

6.6 repeat (建立一個重複發射特定資料的Observable)

可以用來當做計時器,或者間隔性請求網路資料

  Observable.just(1).repeat(2).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer i) throws Exception {
                        mCount++;
                        Log.i(TAG,"第:"+mCount+"次"+"資料為:"+i);
                    }
                });
複製程式碼

列印出來

12-12 05:25:56.585 21915-21915/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 第:1次資料為:1
12-12 05:25:56.585 21915-21915/niezhiyang.cn.rxjava2_android_samples I/CreatActivity: 第:2次資料為:1
複製程式碼

7. 既然講了建立被觀察者(Observable)和觀察者(Observer), 那麼先講一下Schedulers執行緒排程器

如果Observable預設的是在主執行緒中,Observer預設跟隨Observable的執行緒

  • Schedulers.computation()
    計算所使用的 Scheduler。這個計算指的是 CPU 密集型計算,即不會被 I/O 等操作限制效能的操作,例如圖形的計算。這個 Scheduler 使用的固定的執行緒池,大小為 CPU 核數。不要把 I/O 操作放在 computation() 中,否則 I/O 操作的等待時間會浪費 CPU。

  • Schedulers.newThread()
    開啟一個新的執行緒

 Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        Log.i(TAG, "釋出的執行緒是:" + Thread.currentThread().getName());
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .observeOn(Schedulers.newThread())
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "訂閱的執行緒是:" + Thread.currentThread().getName());
                            }
                        });
複製程式碼

列印出來

12-13 06:59:25.085 11730-12398/niezhiyang.cn.rxjava2_android_samples I/SchedulersActivity: 釋出的執行緒是:RxCachedThreadScheduler-2
12-13 06:59:25.086 11730-12573/niezhiyang.cn.rxjava2_android_samples I/SchedulersActivity: 訂閱的執行緒是:RxNewThreadScheduler-1
複製程式碼
  • Schedulers.io()
    主要用於一些耗時操作,比如讀寫檔案,資料庫存取,網路互動等。 這個排程器根據需要,增加或者減少執行緒池中的執行緒數量。需要注意的是Schedulers.i0()中的執行緒池數量是無限制大的,大量的I/0操作將建立許多執行緒,我們需要在效能和執行緒數量中做出取捨。
 Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        Log.i(TAG, "釋出的執行緒是:" + Thread.currentThread().getName());
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .observeOn(Schedulers.io())
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "訂閱的執行緒是:" + Thread.currentThread().getName());
                            }
                        });
複製程式碼

列印出來

12-13 06:58:22.448 11730-12398/niezhiyang.cn.rxjava2_android_samples I/SchedulersActivity: 釋出的執行緒是:RxCachedThreadScheduler-2
12-13 06:58:22.448 11730-12399/niezhiyang.cn.rxjava2_android_samples I/SchedulersActivity: 訂閱的執行緒是:RxCachedThreadScheduler-3
複製程式碼
  • AndroidSchedulers.mainThread()
    Android中專用的,指定的操作在Android的主執行緒(UI執行緒中)執行
 Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        Log.i(TAG, "釋出的執行緒是:" + Thread.currentThread().getName());
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "訂閱的執行緒是:" + Thread.currentThread().getName());
                            }
                        });
複製程式碼

列印出來

12-13 06:54:57.969 11730-11782/niezhiyang.cn.rxjava2_android_samples I/SchedulersActivity: 釋出的執行緒是:RxCachedThreadScheduler-1
12-13 06:54:57.970 11730-11730/niezhiyang.cn.rxjava2_android_samples I/SchedulersActivity: 訂閱的執行緒是:main
複製程式碼

相關文章