友情連結:
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
複製程式碼