前言
- 本系列主要是基于Carson_Ho所寫的《RxJava系列教程》系列文章,對RxJava的相關知識點進行梳理,文中圖片全部來自《RxJava系列教程》。這一些列文章對我幫助很大,通篇把相關知識點和生活上的例子相結合的講解方式,一直是我本人比較欣賞的。特別是將RxJava的原理通過顧客到飯店吃飯這個生活例子來講解,讓我印象很深刻。因為學習的時候,很多概念性的東西都太過于抽象,使用聯想法,將其和生活上的例子結合起來,增加趣味性之余,無疑降低了理解的難度,便于我們學習。對于我來說,學習新的東西,個人的一些心得體會就是,思考的順序應該是這樣的:
- RxJava是什么?
- RxJava用來干什么的?功能是什么?有哪些東西和它的動能是一樣的嗎?
- RxJava優勢在哪里?為什么非要使用它?
- RxJava是怎么樣使用的?
- RxJava的原理是什么?
- ........
定義
- 一個在Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫。
作用
- 實現異步操作,類似于Android中的AsyncTask、Handler作用。
特點
- 基于事件流的鏈式調用,在程序邏輯異常復雜的情況下,仍然可以讓代碼的邏輯保持簡潔。
原理
-
RxJava的異步實現,是通過一種擴展的觀察者模式來實現的。被觀察者(Observable)通過訂閱(Subscribe)按順序發送事件給觀察者(Observer),觀察者(Observer)按順序接收事件和做出對應的響應動作。
- 被觀察者(Observable)
- 作用:決定什么時候觸發事件以及觸發什么樣的事件。
- 創建方法:
- Observable.just(T...) 參數為單個。
- Observable.from(T[])/Observable.fromArray(Iterable<? extends T>)參數為數組或Itera
- 觀察者(Observice)
- 作用:當事件觸發的時候將有怎么樣的行為。
- 實現類有Observer/Subscriber
- 被觀察者(Observable)
舉個例子,顧客到飯店吃飯,如下圖所示
基本使用
-
使用步驟
-
事件類型
示例代碼
public class MainActivity extends AppCompatActivity {
private static final String TAG = "RxJava";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//RxJava的基本使用
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 創建被觀察者 & 生產事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
//觀察者接收到Complete事件后將不再繼續接收任何事件
//所以事件4、事件5沒有在日志中打印出來
emitter.onNext(4);
emitter.onNext(5);
}
}).subscribe(new Observer<Integer>() {
//2.通過訂閱(subscribe)連接觀察者和被觀察者
//3.創建觀察者 & 定義響應事件的行為
//默認最先調用復寫的onSubscribe()方法
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "開始采用subscribe連接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "對Next事件" + value + "作出響應");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "對Error事件作出響應");
}
@Override
public void onComplete() {
Log.d(TAG, "對Complete事件作出響應");
}
});
// 注:整體方法調用順序:觀察者.onSubscribe()> 被觀察者.subscribe()> 觀察者.onNext()>觀察者.onComplete()
}
}
- 運行效果
-
案例
- 由指定的一個drawable文件id取得圖片,并顯示在ImageView中,并在出現異常的時候打印Toast報錯。
private void showImageDemo() {
final int drawID = R.mipmap.ic_launcher;
Observable
.create(new ObservableOnSubscribe<Drawable>() {
@Override
public void subscribe(ObservableEmitter<Drawable> emitter) throws Exception {
Drawable drawable = ContextCompat.getDrawable(MainActivity.this, drawID);
emitter.onNext(drawable);
emitter.onComplete();
}
})
.subscribe(new Observer<Drawable>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Drawable drawable) {
imageView.setImageDrawable(drawable);
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete() {
}
});
}
- 額外說明
觀察者Observer的subscribe()具備多個重載的方法。
可采用Disposable.dispose()切斷觀察者與被觀察者之間的連接。即觀察者無法繼續接收被觀察者的事件,但被觀察者還是可以繼續發送事件。
}).subscribe(new Observer<Integer>() {
// 1. 定義Disposable類變量
private Disposable mDisposable;
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "開始采用subscribe連接");
// 2. 對Disposable類變量賦值
mDisposable = d;
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "對Next事件" + value + "作出響應");
if (value == 2) {
// 3. 設置在接收到第二個事件后切斷了觀察者和被觀察者的連接。
mDisposable.dispose();
Log.d(TAG, "已經切斷了連接" + mDisposable.isDisposed());
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "對Error事件作出響應");
}
@Override
public void onComplete() {
Log.d(TAG, "對Complete事件作出響應");
}
});
- 運行效果