轉自:http://blog.csdn.net/u012124438/article/details/53730717
RxJava可以說是2016年最流行的專案之一了,最近也接觸了一下RxJava,於是想寫一篇部落格,希望能通過這篇部落格讓大家能對其進行了解,本篇部落格是基於RxJava2.0,跟RxJava1.0還是有很多不同的
基礎知識
RxJava的核心就是“非同步”兩個字,其最關鍵的東西就是兩個:
-
Observable(被觀察者)
-
Observer/Subscriber(觀察者)
Observable可以發出一系列的 事件,這裡的事件可以是任何東西,例如網路請求、複雜計算處理、資料庫操作、檔案操作等等,事件執行結束後交給 Observer回撥處理。
Observable可以理解為事件的傳送者,就好像快遞的寄出者,而這些事件就好比快遞
Observer可以理解為事件的接收者,就好像快遞的接收者
那他們之間是如何進行聯絡的呢?答案就是通過subscribe()方法,下面的程式碼就是RXJAVA中Observable與Observer進行關聯的典型方式:
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(5);
e.onNext(6);
e.onNext(7);
e.onNext(8);
e.onComplete();
}
});
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "subscribe");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, value.toString());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "error");
}
@Override
public void onComplete() {
Log.d(TAG, "complete");
}
};
observable.subscribe(observer);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
執行專案,我們可以看到,數字已經列印出來
這裡需要強調的是: 只有當觀察者和被觀察者建立連線之後, 被觀察者才會開始傳送事件. 也就是呼叫了subscribe()方法之後才開始傳送事件.
上面我們看到觀察者和被觀察者的邏輯是分開寫的,那能不能合在一起寫呢?答案是肯定的,這也是RxJava比較突出的優點,那就是鏈式操作,程式碼如下:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(5);
e.onNext(6);
e.onNext(7);
e.onNext(8);
e.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "subscribe");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, value.toString());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "error");
}
@Override
public void onComplete() {
Log.d(TAG, "complete");
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
有時候,你可能覺得,我就列印幾個數,還要把Observable寫的那麼麻煩,能不能簡便一點呢?答案是肯定的,RxJava內建了很多簡化建立Observable物件的函式,比如Observable.just就是用來建立只發出一個事件就結束的Observable物件,上面建立Observable物件的程式碼可以簡化為一行
Observable<String> observable = Observable.just("hello");
同樣對於Observer,這個例子中,我們其實並不關心OnComplete和OnError,我們只需要在onNext的時候做一些處理,這時候就可以使用Consumer類。
Observable<String> observable = Observable.just("hello");
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
};
observable.subscribe(consumer);
其實在RxJava中,我們可以為 Observer中的三種狀態根據自身需要分別建立一個回撥動作,通過Action 來替代onComplete():,通過Consumer來替代 onError(Throwable t)和onNext(T t)
Observable<String> observable = Observable.just("hello");
Action onCompleteAction = new Action() {
@Override
public void run() throws Exception {
Log.i(TAG, "complete");
}
};
Consumer<String> onNextConsumer = new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, s);
}
};
Consumer<Throwable> onErrorConsumer = new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.i(TAG, "error");
}
};
observable.subscribe(onNextConsumer, onErrorConsumer, onCompleteAction);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
Observable.just同樣可以傳送多個引數
Observable observable = Observable.just("you", "are", "beautiful");
Consumer<String> onNextConsumer = new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, s);
}
};
observable.subscribe(onNextConsumer);
例子:來一個簡單的例子來了解事件的產生到消費、訂閱的過程:從res/mipmap中取出一張圖片,顯示在ImageView上。
final ImageView ivLogo = (ImageView) findViewById(R.id.logo);
Observable.create(new ObservableOnSubscribe<Drawable>() {
@Override
public void subscribe(ObservableEmitter<Drawable> e) throws Exception {
Drawable drawable = ContextCompat.getDrawable(MainActivity.this, R.mipmap.ic_launcher);
e.onNext(drawable);
e.onComplete();
}
}).subscribe(new Observer<Drawable>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Drawable value) {
ivLogo.setImageDrawable(value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
這樣就完成了一個簡單的圖片的設定
ObservableEmitter和Disposable
ObservableEmitter: ObservableEmitter可以理解為發射器,這個就是用來發出事件的,它可以發出三種型別的事件,通過呼叫emitter的onNext(T value)、onComplete()和onError(Throwable error)就可以分別發出next事件、complete事件和error事件。
注意:但是事件的傳送是有一定的規定的,就好比寄快遞也要有一定要求,不是什麼都能寄的:
1.被觀察者可以傳送無限個onNext, 觀察者也可以接收無限個onNext.
2.當Observable傳送了一個onComplete後, Observable的onComplete之後的事件將會繼續傳送, 而Observer收到onComplete事件之後將不再繼續接收事件.
3.當Observable傳送了一個onError後, Observable中onError之後的事件將繼續傳送, 而Observer收到onError事件之後將不再繼續接收事件.
4.Observable可以不傳送onComplete或onError.
5.最為關鍵的是onComplete和onError必須唯一併且互斥, 即不能發多個onComplete, 也不能發多個onError, 也不能先發一個onComplete, 然後再發一個onError, 反之亦然
注: 關於onComplete和onError唯一併且互斥這一點, 是需要自行在程式碼中進行控制, 如果你的程式碼邏輯中違背了這個規則, 並不一定會導致程式崩潰. 比如傳送多個onComplete是可以正常執行的, 依然是收到第一個onComplete就不再接收了, 但若是傳送多個onError, 則收到第二個onError事件會導致程式會崩潰.當我們寫多個onComplete時,不會報錯
當我們又有onComplete又有onError時,發現在呼叫onComplete後會爆出異常
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(5);
e.onNext(6);
e.onNext(7);
e.onNext(8);
e.onError(new NullPointerException());
e.onComplete();
}
})
這是onComplete在onError前呼叫的情況
當我們寫兩個onError時,會先接受前面的所有事件,最後才報錯
介紹了ObservableEmitter, 接下來介紹Disposable, 當呼叫dispose()方法時, 它就會將觀察者和被觀察者的聯絡切斷, 從而導致觀察者收不到事件.
注意: 呼叫dispose()並不會導致Observable不再繼續傳送事件, Observable會繼續傳送剩餘的事件.
看一下下面這個例子:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emitter 1");
emitter.onNext(1);
Log.d(TAG, "emitter 2");
emitter.onNext(2);
Log.d(TAG, "emitter 3");
emitter.onNext(3);
Log.d(TAG, "emitter complete");
emitter.onComplete();
Log.d(TAG, "emitter 4");
emitter.onNext(4);
}
}).subscribe(new Observer<Integer>() {
private Disposable mDisposable;
private int i;
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "subscribe");
mDisposable = d;
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "onNext: " + value);
i++;
if (i == 2) {
Log.d(TAG, "dispose");
mDisposable.dispose();
Log.d(TAG, "isDisposed : " + mDisposable.isDisposed());
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "error");
}
@Override
public void onComplete() {
Log.d(TAG, "complete");
}
});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
列印如下:
在收到onNext 2這個事件後, 我們中斷了聯絡, 但是Observable
仍然傳送了3, complete, 4這幾個事件, 而且Observable
並沒有因為傳送了onComplete而停止. 同時可以看到Observer的onSubscribe()方法是最先呼叫的.
subscribe()有多個過載的方法:
public final Disposable subscribe() {}
public final Disposable subscribe(Consumer<? super T> onNext) {}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
public final void subscribe(Observer<? super T> observer) {}
不帶任何引數的subscribe() 表示Observer不關心任何事件,Observable傳送什麼資料都隨你
帶有一個Consumer引數的方法表示Observer只關心onNext事件, 其他的事件我假裝沒看見, 因此我們如果只需要onNext事件可以這麼寫:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emitter 1");
emitter.onNext(1);
Log.d(TAG, "emitter 2");
emitter.onNext(2);
Log.d(TAG, "emitter 3");
emitter.onNext(3);
Log.d(TAG, "emitter complete");
emitter.onComplete();
Log.d(TAG, "emitter 4");
emitter.onNext(4);
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "onNext: " + integer);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
其他方式也是類似的方式
執行緒排程
正常情況下, Observer和Observable是工作在同一個執行緒中的, 也就是說Observable在哪個執行緒發事件, Observer就在哪個執行緒接收事件.
RxJava中, 當我們在主執行緒中去建立一個Observable來傳送事件, 則這個Observable預設就在主執行緒傳送事件.
當我們在主執行緒去建立一個Observer來接收事件, 則這個Observer預設就在主執行緒中接收事件,但其實在現實工作中我們更多的是需要進行執行緒切換的,最常見的例子就是在子執行緒中請求網路資料,在主執行緒中進行展示
要達到這個目的, 我們需要先改變Observable傳送事件的執行緒, 讓它去子執行緒中傳送事件, 然後再改變Observer的執行緒, 讓它去主執行緒接收事件. 通過RxJava內建的執行緒排程器可以很輕鬆的做到這一點. 接下來看一段程式碼:
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "Observable thread is : " + Thread.currentThread().getName());
Log.d(TAG, "emitter 1");
emitter.onNext(1);
}
});
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
Log.d(TAG, "onNext: " + integer);
}
};
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(consumer);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
可以看到, observable傳送事件的執行緒的確改變了, 是在一個叫 RxNewThreadScheduler-1的執行緒中傳送的事件, 而consumer 仍然在主執行緒中接收事件, 這說明我們的目的達成了, 接下來看看是如何做到的.
這段程式碼只不過是增加了兩行程式碼:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
簡單的來說, subscribeOn() 指定的是Observable傳送事件的執行緒, observeOn() 指定的是Observer接收事件的執行緒.
多次指定Observable的執行緒只有第一次指定的有效, 也就是說多次呼叫subscribeOn() 只有第一次的有效, 其餘的會被忽略.
多次指定Observer的執行緒是可以的, 也就是說每呼叫一次observeOn() , Observer的執行緒就會切換一次.例如:
observable.subscribeOn(Schedulers.newThread())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.subscribe(consumer)
這段程式碼中指定了兩次上游傳送事件的執行緒, 分別是newThread和IO執行緒, 下游也指定了兩次執行緒,分別是main和IO執行緒. 執行結果為:
可以看到, Observable雖然指定了兩次執行緒, 但只有第一次指定的有效, 依然是在RxNewThreadScheduler執行緒中, 而Observer則跑到了RxCachedThreadScheduler 中, 這個CacheThread其實就是IO執行緒池中的一個.
在 RxJava 中,提供了一個名為 Scheduler 的執行緒排程器,RxJava 內部提供了4個排程器,分別是:
Schedulers.io(): I/O 操作(讀寫檔案、資料庫、網路請求等),與newThread()差不多,區別在於io() 的內部實現是是用一個無數量上限的執行緒池,可以重用空閒的執行緒,因此多數情況下 io() 效率比 newThread() 更高。值得注意的是,在 io() 下,不要進行大量的計算,以免產生不必要的執行緒;
Schedulers.newThread(): 開啟新執行緒操作;
Schedulers.immediate(): 預設指定的執行緒,也就是當前執行緒;
Schedulers.computation():計算所使用的排程器。這個計算指的是 CPU 密集型計算,即不會被 I/O等操作限制效能的操作,例如圖形的計算。這個 Scheduler 使用的固定的執行緒池,大小為 CPU 核數。值得注意的是,不要把 I/O 操作放在 computation() 中,否則 I/O 操作的等待時間會浪費 CPU;
AndroidSchedulers.mainThread(): RxJava 擴充套件的 Android 主執行緒;
這些內建的Scheduler已經足夠滿足我們開發的需求, 因此我們應該使用內建的這些選項, 在RxJava內部使用的是執行緒池來維護這些執行緒, 所有效率也比較高.
例子:還是用之前設定圖片的例子,這次我們在子執行緒中進行網路請求獲取圖片,在主執行緒中對圖片進行設定
final ImageView ivLogo = (ImageView) findViewById(R.id.logo);
Observable.create(new ObservableOnSubscribe<Drawable>() {
@Override
public void subscribe(ObservableEmitter<Drawable> e) throws Exception {
try {
Drawable drawable = Drawable.createFromStream(new URL("https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2502144641,437990411&fm=80&w=179&h=119&img.JPEG").openStream(), "src");
e.onNext(drawable);
} catch (IOException error) {
e.onError(error);
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Drawable>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Drawable value) {
ivLogo.setImageDrawable(value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
這段程式碼就做一件事,在 io 執行緒載入一張網路圖片,載入完畢之後在主執行緒中顯示到ImageView上。
操作符的使用
在瞭解基本知識和執行緒排程後,我們來學習一下RxJava各種神奇的操作符
Map
Map是RxJava中最簡單的一個變換操作符了, 它的作用就是對Observable傳送的每一個事件應用一個函式, 使得每一個事件都按照指定的函式去變化.
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "This is result " + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
在Observable我們傳送的是數字型別, 而在Observer我們接收的是String型別, 中間起轉換作用的就是Map操作符, 執行結果為:
通過Map, 可以將Observable發來的事件轉換為任意的型別, 可以是一個Object, 也可以是一個集合,功能非常強大
例子:還是以圖片載入的例子,我們傳進來一個圖片的路徑,然後通過Map進行轉換成drawble再傳送給觀察者
final ImageView ivLogo = (ImageView) findViewById(R.id.logo);
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("https://ss2.baidu.com/-vo3dSag_xI4khGko9WTAnF6hhy/image/h%3D200/sign=4db5130a073b5bb5a1d727fe06d2d523/cf1b9d16fdfaaf51965f931e885494eef11f7ad6.jpg");
}
}).map(new Function<String, Drawable>() {
@Override
public Drawable apply(String url) throws Exception {
try {
Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), "src");
return drawable;
} catch (IOException e) {
}
return null;
}
}) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Drawable>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Drawable value) {
if (value != null) {
ivLogo.setImageDrawable(value);
}
}
@Override
public void onError(Throwable e) {
Log.e(TAG, e.toString());
}
@Override
public void onComplete() {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
效果如下:
經過改寫程式碼後,有什麼變化呢? Observable 建立了一個 String 事件,也就是產生一個url,通過 map 操作符進行變換,返回Drawable物件,這個變換指的就是通過url進行網路圖片請求,返回一個Drawable。所以簡單的來說就是把String事件,轉換為Drawable事件。邏輯表示就是
Observable –> map變換 –> Observable
FlatMap
FlatMap將一個傳送事件的Observable變換為多個傳送事件的Observables,然後將它們發射的事件合併後放進一個單獨的Observable裡.
Observable每傳送一個事件, flatMap都將對其進行轉換, 然後傳送轉換之後的新的事件, Observer接收到的就是轉換後傳送的資料. 這裡需要注意的是, flatMap並不保證事件的順序, 如果需要保證順序則需要使用concatMap.
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("I am value " + integer);
}
return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
效果如下:
Map 與 flatMap 這兩個操作符的共同點在於,他們都是把一個物件轉換為另一個物件,但須注意以下這些特點:
1.flatMap 返回的是一個Observable物件,而 map 返回的是一個普通轉換後的物件;
2.flatMap 返回的Observable物件並不是直接傳送到Subscriber的回撥中,而是重新建立一個Observable物件,並啟用這個Observable物件,使之開始傳送事件;而 map 變換後返回的物件直接發到Subscriber回撥中;
3.flatMap 變換後產生的每一個Observable物件傳送的事件,最後都匯入同一個Observable,進而傳送給Subscriber回撥;
4.map返回型別 與 flatMap 返回的Observable事件型別,可以與原來的事件型別一樣;
5.可以對一個Observable多次使用 map 和 flatMap;
鑑於 flatMap 自身強大的功能,這常常被用於 巢狀的非同步操作,例如巢狀網路請求。傳統的巢狀請求,一般都是在前一個請求的 onSuccess() 回撥裡面發起新的請求,這樣一旦巢狀多個的話,縮排就是大問題了,而且嚴重的影響程式碼的可讀性。而RxJava巢狀網路請求仍然通過鏈式結構,保持程式碼邏輯的清晰!舉個栗子:
public interface Api {
@GET
Observable<LoginResponse> login(@Body LoginRequest request);
@GET
Observable<RegisterResponse> register(@Body RegisterRequest request);
}
接著建立一個Retrofit客戶端:
private static Retrofit create() {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
builder.readTimeout(10, TimeUnit.SECONDS)
builder.connectTimeout(9, TimeUnit.SECONDS)
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
builder.addInterceptor(interceptor)
}
return new Retrofit.Builder().baseUrl(ENDPOINT)
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
發起請求就很簡單了:
Api api = retrofit.create(Api.class);
api.login(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<LoginResponse>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(LoginResponse value) {}
@Override
public void onError(Throwable e) {
Toast.makeText(mContext, "登入失敗", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete() {
Toast.makeText(mContext, "登入成功", Toast.LENGTH_SHORT).show();
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
concatMap
這裡也簡單說一下concatMap吧, 它和flatMap的作用幾乎一模一樣, 只是它的結果是嚴格按照上游傳送的順序來傳送的, 來看個程式碼吧:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).concatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("I am value " + integer);
}
return Observable.fromIterable(list).delay(10,TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
只是將之前的flatMap改為了concatMap, 其餘原封不動, 執行結果如下:
可以看到, 結果仍然是有序的.
ZIP
Zip通過一個函式將多個Observable傳送的事件結合到一起,然後傳送這些組合到一起的事件. 它按照嚴格的順序應用這個函式。它只發射與發射資料項最少的那個Observable一樣多的資料。
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emitter 1");
emitter.onNext(1);
Log.d(TAG, "emitter 2");
emitter.onNext(2);
Log.d(TAG, "emitter 3");
emitter.onNext(3);
Log.d(TAG, "emitter 4");
emitter.onNext(4);
Log.d(TAG, "emit complete1");
emitter.onComplete();
}
});
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "emitter A");
emitter.onNext("A");
Log.d(TAG, "emitter B");
emitter.onNext("B");
Log.d(TAG, "emitter C");
emitter.onNext("C");
Log.d(TAG, "emitter complete2");
emitter.onComplete();
}
});
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(String value) {
Log.d(TAG, "onNext: " + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
我們分別建立了observable, 一個傳送1,2,3,4,Complete, 另一個傳送A,B,C,Complete, 接著用Zip把發出的事件組合, 來看看執行結果吧:
觀察發現observable1傳送事件後,observable2才傳送
這是因為我們兩個observable都是執行在同一個執行緒裡, 同一個執行緒裡執行程式碼肯定有先後順序呀.
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emit 1");
emitter.onNext(1);
Thread.sleep(1000);
Log.d(TAG, "emit 2");
emitter.onNext(2);
Thread.sleep(1000);
Log.d(TAG, "emit 3");
emitter.onNext(3);
Thread.sleep(1000);
Log.d(TAG, "emit 4");
emitter.onNext(4);
Thread.sleep(1000);
Log.d(TAG, "emit complete1");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "emit A");
emitter.onNext("A");
Thread.sleep(1000);
Log.d(TAG, "emit B");
emitter.onNext("B");
Thread.sleep(1000);
Log.d(TAG, "emit C");
emitter.onNext("C");
Thread.sleep(1000);
Log.d(TAG, "emit complete2");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(String value) {
Log.d(TAG, "onNext: " + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
好了, 這次我們讓事件都在IO執行緒裡傳送事件, 再來看看執行結果:
第一個observable明明傳送了四個資料+一個Complete, 之前明明還有的, 為啥到這裡沒了呢?
這是因為我們之前說了, zip傳送的事件數量跟observable中傳送事件最少的那一個的事件數量是有關的, 在這個例子裡我們observable2只傳送了三個事件然後就傳送了Complete, 這個時候儘管observable1還有事件4 和事件Complete 沒有傳送, 但是它們發不傳送還有什麼意義呢?
from
在RxJava的from操作符到2.0已經被拆分成了3個,fromArray, fromIterable, fromFuture接收一個集合作為輸入,然後每次輸出一個元素給subscriber。
Observable.fromArray(new Integer[]{1, 2, 3, 4, 5}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "number:" + integer);
}
});
注意:如果from()裡面執行了耗時操作,即使使用了subscribeOn(Schedulers.io()),仍然是在主執行緒執行,可能會造成介面卡頓甚至崩潰,所以耗時操作還是使用Observable.create(…);
filter
條件過濾,去除不符合某些條件的事件。舉個栗子:
Observable.fromArray(new Integer[]{1, 2, 3, 4, 5})
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Exception {
return integer % 2 == 0;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "number:" + integer);
}
});
take
最多保留的事件數。
Observable.just("1", "2", "6", "3", "4", "5").take(2).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
Log.d(TAG,value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
可以發現我們傳送了6個String,最後只列印了前兩個,這就是take過濾掉的結果
doOnNext
如果你想在處理下一個事件之前做某些事,就可以呼叫該方法
Observable.fromArray(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}).filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Exception {
return integer % 2 == 0;
}
})
.take(3).doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "hahcode = " + integer.hashCode() + "");
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.i(TAG, "number = " + value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
debounce
debounce也是用於事件的過濾,可以指定過濾事件的時間間隔
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
int i = 0;
int[] times = new int[]{100, 1000};
while (true) {
i++;
if (i >= 100)
break;
e.onNext(i);
try {
Thread.sleep(times[i % 2]);
} catch (InterruptedException error) {
error.printStackTrace();
}
}
e.onComplete();
}
})
.debounce(400, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onError(Throwable e) {
Log.e(TAG, e.toString());
}
@Override
public void onComplete() {
Log.i(TAG, "complete");
}
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.i(TAG, "integer = " + integer);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
compose
與 flatMap 類似,都是進行變換,返回Observable物件,啟用併傳送事件。
1.compose 是唯一一個能夠從資料流中得到原始Observable的操作符,所以,那些需要對整個資料流產生作用的操作(比如,subscribeOn()和observeOn())需要使用 compose 來實現。相較而言,如果在flatMap()中使用subscribeOn()或者observeOn(),那麼它僅僅對在flatMap 中建立的Observable起作用,而不會對剩下的流產生影響。這樣就可以簡化subscribeOn()以及observeOn()的呼叫次數了。
2.compose 是對 Observable 整體的變換,換句話說, flatMap 轉換Observable裡的每一個事件,而 compose 轉換的是整個Observable資料流。
3.flatMap 每傳送一個事件都建立一個 Observable,所以效率較低。而 compose 操作符只在主幹資料流上執行操作。
4.建議使用 compose 代替 flatMap。
First
只傳送符合條件的第一個事件。可以與contact操作符,做網路快取。
例子:依次檢查Disk與Network,如果Disk存在快取,則不做網路請求,否則進行網路請求。
Observable<BookList> fromDisk = Observable.create(new Observable.OnSubscribe<BookList>() {
@Override
public void call(Subscriber<? super BookList> subscriber) {
BookList list = getFromDisk();
if (list != null) {
subscriber.onNext(list);
} else {
subscriber.onCompleted();
}
}
});
Observable<BookList> fromNetWork = bookApi.getBookDetailDisscussionList();
Observable.concat(fromDisk, fromNetWork)
.first()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<BookList>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(BookList discussionList) {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
Single
Single與Observable類似,相當於是他的精簡版。訂閱者回撥的不是OnNext/OnError/onCompleted,而是回撥OnSuccess/OnError。
Single.create(new SingleOnSubscribe<Object>() {
@Override
public void subscribe(SingleEmitter<Object> e) throws Exception {
e.onSuccess("hello world");
}
}).subscribe(new SingleObserver<Object>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(Object value) {
Log.i(TAG, value.toString());
}
@Override
public void onError(Throwable e) {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
可以配合debounce,避免SearchEditText頻繁請求。
final Subject subject = PublishSubject.create();
subject.debounce(400, TimeUnit.MILLISECONDS)
.subscribe(new Observer() {
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
});
edittext.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
subject.onNext(s.toString());
}
@Override
public void afterTextChanged(Editable s) { }
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
RxJava的一些使用場景
場景1:
取資料,首先檢查記憶體是否有快取
然後檢查檔案快取中是否有
最後才從網路中取
前面任何一個條件滿足,就不會執行後面的
final Observable<String> memory = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
if (memoryCache != null) {
emitter.onNext(memoryCache);
} else {
emitter.onComplete();
}
}
});
final Observable<String> disk = Observable.create(new ObservableOnSubscribe<String>() {
String cachePref = getSharedPreferences("rxdeni",MODE_PRIVATE).getString("cache",null);
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
if (cachePref != null) {
emitter.onNext(cachePref);
} else {
emitter.onComplete();
}
}
});
Observable<String> network = Observable.just("network");
Observable.concat(memory, disk, network).firstElement()
.subscribeOn(Schedulers.newThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println("--------------subscribe: " + s);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
場景2:介面需要等到多個介面併發取完資料,再更新
Observable<String> observable1 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("haha");
}
}).subscribeOn(Schedulers.newThread());
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("hehe");
}
}).subscribeOn(Schedulers.newThread());
Observable.merge(observable1, observable2)
.subscribeOn(Schedulers.newThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
Log.d(TAG,value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
場景3:介面按鈕需要防止連續點選的情況
RxView.clicks(button)
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe(new Observer<Object>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Object o) {
Log.i(TAG, "do clicked!");
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
場景4:響應式的介面
比如勾選了某個checkbox,自動更新對應的preference
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this)
RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences)
Preference<Boolean> checked = rxPreferences.getBoolean("checked", true)
CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test)
RxCompoundButton.checkedChanges(checkBox)
.subscribe(checked.asAction())
場景5:複雜的資料變換
Observable.just("1", "2", "6", "3", "4", "5")
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return Integer.parseInt(s);
}
}).filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Exception {
return integer.intValue()%2 == 0;
}
}).distinct().take(2).reduce(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
return integer.intValue() + integer2.intValue();
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG,integer.toString());
}
});