Rxjava2 二三四五六訪
Reactive Extensions for the JVM — a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
今天要來講講已經出來很久很久的 Rxjava,如果你是想要知道 Rxjava 是什麼,以及為什麼要使用他,而他又有什麼好處呢?網路上就有很多大神寫的文章,這裡我就不再贅(複製)述(貼上)了。所以這篇文章的重點會放在幫助你了解 Rxjava 的基本觀念。
附上幾篇我覺得寫得很棒的文章,這篇文章的內容也大多是我從文章學到的東西再整理出來,所以其實看連結的文章也可以(咦?)
首先
最重要的就是先引入 Rxjava 的 Library 囉
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
這樣就可以在 Android Studio 中正式開始使用 Rxjava2了
Rxjava2 的基本物件
Rxjava2 裡最主要會用到的其實就是兩個物件:Observer 和 Observable
以及subscribe這個指令,只要搞懂他們的關係,接下來就很輕鬆囉!
在看了無數文章後我覺得用檯燈和開關按鈕的例子對我來說是最好理解的,
你可以想像檯燈是觀察者 (Observer),而開關按鈕是被觀察者 (Observable)。
當你打開開關時,相當於發送了一個開燈(on) 的訊息給檯燈;當你關閉開關時,相當於發送了一個關燈(off) 的訊息給檯燈。
<img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/800/1*JKxeQZye7DoUh0zVGcezRA.png">
而你可以想像開關按鈕和檯燈之間會有一條電線 ,這樣開關按鈕才能傳遞訊息給檯燈,而subscribe 這個指令就等同是這條電線,連接了開關按鈕和檯燈 。
如果你能理解這些概念,那我們來實際看看 code 要怎麼寫吧!
先建立一個 Obsever (檯燈)的物件:
/* 想像是檯燈:接收來自開關按鈕的訊息 */
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(String string) {
// 收到 開/關 的訊息
Log.d(TAG, "onNext: " + string);
}
@Override
public void onError(Throwable t) {
Log.d(TAG, "onError:" + t.getLocalizedMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
再建立 Observable(開關按鈕) 物件:
/* 想像是開關按鈕:發送 開/關 的訊息給檯燈 */
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 使用 ObservableEmitter 來發送訊息
emitter.onNext("on");
emitter.onNext("off");
emitter.onNext("on");
emitter.onComplete();
}
});
// 偷懶的寫法,和上面的結果完全相同,會自動呼叫onComplete
Observable.just("on", "off", "on").subscribe(observer);
最後再用subscribe (電線)把他們連接起來就完成囉!
// 把檯燈跟開關按鈕用電線連接起來
observable.subscribe(observer);
你可以在 Logcat 裡面看到 Observer 收到的訊息
看到這邊你可能會有個疑問
想像上應該是檯燈訂閱了開關按鈕的事件,為什麼反過來了呢?
簡單來說這是 Rxjava 為了保持流式 API 的呼叫風格所做的調整你可以看看下面這個例子:
Observable.just(1, 0, 1)
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
if (integer.intValue() == 0) {
return "off";
} else {
return "on";
}
}
})
.subscribe(consumer);
可以看到開頭使用 Observable 這個主體後,不需要再改變主體就能完成一連串的 API 呼叫。
那假如今天反過來是檯燈訂閱開關呢:
Observable.just(1, 0, 1)
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
if (integer.intValue() == 0) {
return "off";
} else {
return "on";
}
}
});
// 注意!這不是正確用法哦!只是示例用!
Observer.subscribe(observable);
我們就會需要拆分成兩個主體來完成,變得比較麻煩。
當然這邊只是做一個比較簡單的說明,如果想要深入地理解可以再多多參考其他文章。如果還是無法理解的話也沒關係,我建議可以暫時先背起來這個用法,用久了你就會自然而然地發現這樣做的好處囉!
下次我們再來說說一些基本的 operators 的用法吧!今天就先到這邊告一個段落,謝謝大家的收看!
P.S. 文章中用到的範例有寫成 Project 上傳到 Github哦,往後會隨著文章持續更新!喜歡的話歡迎幫我按個 star 哈哈哈哈哈,我們下次見!
最後,為什麼標題是二三四五六訪呢?
因為我不斷地學了又忘學了又忘好幾十次了
所以才有這篇文章的誕生幫助金魚腦的我記憶
如果你也是金魚腦的一員歡迎追蹤我(?)