繼續之前的RxJava 操作符系列文檔,今天來研究一下do 操作符,也可以理解爲 rxJava 各種事件的回調,比如當發生了onError ,我想在此做些什麼,就可以使用一個回調操作,就可以用doOnError () 來實現。好了,老規矩,先列出參考文章
http://reactivex.io/documentation/operators/do.html
來看看官方解釋
register an action to take upon a variety of Observable lifecycle events
意思就是註冊一個動作來監聽生命週期的各個事件。想想有什麼事件呢? 訂閱,取消訂閱,onNext, onError, onComplete, 終止,結束等等,官方列舉有如下事件:
代碼展示
Observable<String> mStringObservable;
Observable<String> mStringErorObservable;
Observer<String> mStringSubscriber;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_do_operation);
mStringErorObservable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 5; i++) {
if(i == 3) {
emitter.onError(new Throwable("ERROR"));
}else{
emitter.onNext(i + "");
}
}
emitter.onComplete();
}
});
mStringObservable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 5; i++) {
emitter.onNext(i + "");
}
emitter.onComplete();
}
});
mStringSubscriber = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: ");
}
@Override
public void onNext(String s) {
Log.d(TAG, "onNext: " + s);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
};
doError 、doOnNext 、 doComplete
public void doOnError(View view){
mStringErorObservable.doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d(TAG, "doOnError accept: " + throwable.getMessage());
}
}).subscribe(mStringSubscriber);
}
日誌打印:
D/DoOperateActivity: onSubscribe:
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: doOnError accept: ERROR
D/DoOperateActivity: onError: ERROR
結果分析:
由於註冊了DoOnError 函數,當遇到錯誤時,會先觸發 doOnError 回調,在執行onError 函數;類似的,onNext , onComplete對應的回調函數都會先於其本身執行。另外的,遇到錯誤onError後,onComplete 不會被執行,相當於異常終止,如果想要執行onComplete, 可以參考Error Handling 裏面的操作符。
public void doOnCompleteOnNextdoOnError(View view){
mStringObservable.doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d(TAG, "accept: " + throwable.getMessage());
}
}).doOnNext(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: " + s);
}
}).doOnComplete(new Action() {
@Override
public void run() throws Exception {
Log.d(TAG, "run: doOnComplete");
}
}).subscribe(mStringSubscriber);
}
日誌打印:
D/DoOperateActivity: onSubscribe:
D/DoOperateActivity: accept: 0
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: accept: 1
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: accept: 2
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: accept: 3
D/DoOperateActivity: onNext: 3
D/DoOperateActivity: accept: 4
D/DoOperateActivity: onNext: 4
D/DoOperateActivity: run: doOnComplete
D/DoOperateActivity: onComplete:
結果分析:
這次用了一個正常的數據源,doOnNext 會在 onNext前調用,同理 doOnComplete 也是的。和第一個分析一致。注意:想要回調執行doOnComplete , 數據源必須調用onComplete , 否則觀察者不會執行onComplete, 而doOnComplete 的回調基於onComplete的,所以這樣說大家應該明白了。
doOnEach
The doOnEach operator allows you to establish a callback that the resulting Observable will call each time it emits an item. You can pass this callback either in the form of an Action that takes an onNext variety of Notification as its sole parameter, or you can pass in an Observer whose onNext method will be called as if it had subscribed to the Observable.
doOnEach運算符允許您建立一個回調,結果Observable每次發出一個項目時都會調用它。 您可以以Action的形式傳遞此回調,該Action將onNext各種Notification作爲其唯一參數,或者您可以傳入一個Observer,其onNext方法將被調用,就好像它已訂閱了Observable一樣。
就是會對觀察者的onNext onError onComplete 三個方法做出回調
我們可以看代碼:
public void doEach(View view){
mStringObservable.doOnEach(new Consumer<Notification<String>>() {
@Override
public void accept(Notification<String> stringNotification) throws Exception {
Log.d(TAG, "accept: ");
}
}).subscribe(mStringSubscriber);
mStringObservable.doOnEach(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "doOnEach onSubscribe: ");
}
@Override
public void onNext(String s) {
Log.d(TAG, " doOnEach onNext: " + s);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "doOnEach onError: " + e);
}
@Override
public void onComplete() {
Log.d(TAG, "doOnEach onComplete: ");
}
}).subscribe(mStringSubscriber);
}
日誌打印:
D/DoOperateActivity: onSubscribe:
D/DoOperateActivity: accept:
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: accept:
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: accept:
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: accept:
D/DoOperateActivity: onNext: 3
D/DoOperateActivity: accept:
D/DoOperateActivity: onNext: 4
D/DoOperateActivity: accept:
D/DoOperateActivity: onComplete:
D/DoOperateActivity: onSubscribe:
D/DoOperateActivity: doOnEach onNext: 0
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: doOnEach onNext: 1
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: doOnEach onNext: 2
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: doOnEach onNext: 3
D/DoOperateActivity: onNext: 3
D/DoOperateActivity: doOnEach onNext: 4
D/DoOperateActivity: onNext: 4
D/DoOperateActivity: doOnEach onComplete:
D/DoOperateActivity: onComplete:
結果分析:
對onNext ,onComplete 都做出了響應,有點組合doOnNext 和 doOnComplete的意思。
然後我把數據源換成了mStringErrorObservale 後,日誌打印變成了
D/DoOperateActivity: onSubscribe:
D/DoOperateActivity: doOnEach onNext: 0
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: doOnEach onNext: 1
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: doOnEach onNext: 2
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: doOnEach onError: java.lang.Throwable: ERROR
D/DoOperateActivity: onError: ERROR
其他的Do操作符
public void doOther(View view){
mStringErorObservable.doOnTerminate(new Action() {
@Override
public void run() throws Exception {
Log.d(TAG, "doOnTerminate run: ");
}
}).doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
Log.d(TAG, "doOnSubscribe accept: ");
}
}).doOnLifecycle(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
Log.d(TAG, "doOnLifecycle accept: ");
}
}, new Action() {
@Override
public void run() throws Exception {
Log.d(TAG, "doOnLifecycle run: ");
}
}).doFinally(new Action() {
@Override
public void run() throws Exception {
Log.d(TAG, "run: doFinally");
}
}).doAfterTerminate(new Action() {
@Override
public void run() throws Exception {
Log.d(TAG, "run: doAfterTerminate");
}
}).subscribe(mStringSubscriber);
}
日誌打印:
D/DoOperateActivity: doOnSubscribe accept:
D/DoOperateActivity: doOnLifecycle accept:
D/DoOperateActivity: onSubscribe:
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: doOnTerminate run:
D/DoOperateActivity: onError: ERROR
D/DoOperateActivity: run: doAfterTerminate
D/DoOperateActivity: run: doFinally
其他的操作符,我們都能見名曉意,不用一一解釋了。
好了,do相關的操作符介紹完了,歸納就是一句話:對各種事件監聽並做出迴應。