閒談RxJava
- RxJava:"a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫)
- 異步。它其實就是一個實現異步操作的庫,基於觀察者模式,而且是鏈式調用的。
RxJava的三個基本元素
被觀察者(Observable)、觀察者(Observer)、訂閱(subscribe)。
1、創建被觀察者:
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(0);
e.onNext(1);
e.onNext(2);
e.onComplete();
}
});
2、創建被觀察者:
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer o) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
};
3、建立訂閱關係:
observable.subscribe(observer);
- 被觀察者的創建常用三種:
Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
emitter.onNext(0);
emitter.onNext(1);
emitter.onNext(2);
emitter.onComplete();
});
Observable.just(0);
Observable.fromIterable(Arrays.asList(0,1, 2));
- 觀察者的創建有兩種:
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer o) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
};
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {}
};
- 訂閱關係有四種:
Disposable subscribe();
void subscribe(Observer<? super T> observer);
Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,Action onComplete, Consumer<? super Disposable> onSubscribe);
<E extends Observer<? super T>> E subscribeWith(E observer);
調度器Scheduler
- Schedulers.computation():代表CPU計算密集型的操作, 例如需要大量計算的操作。
- Schedulers.newThread():直接開啓一個新的線程。
- Schedulers.io():開啓一個io線程,完成對網絡請求和文件讀寫數據庫增刪改查等操作。那io和newThread有什麼區別吶?newThread不管有沒有線程,他都會去重新開啓一個新的線程來進行操作,並且沒線程池維護。但是io的線程是無上限的,並且最大的一個好處是它會去重用空閒的線程,而不是每次都開啓一個線程來使用,效率上比newThread要高。所以,一般我們在使用的時候是直接使用io這個方法。
- AndroidSchedulers.mainThread():android一個專門的線程,用來指定操作在主線程完成。
RxJava實現線程切換
subscribeOn():指定Observable被觀察者在哪個線程執行。要注意的是,如果多次調用此方法,只有第一次有效。
observeOn():指定Observe觀察者在哪個線程中執行。多次指定觀察者接收線程是可以的,每調用一次observerOn(),下游的線程就會切換一次。
- 代碼探索:
Observable.just(0)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",當前線程mainThread = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.io())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",當前線程io = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.newThread())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",當前線程newThread = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.computation())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",當前線程computation = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.single())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",當前線程single = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(AndroidSchedulers.mainThread())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",當前線程mainThread = " + Thread.currentThread().getName());
return ++integer;
})
.subscribe();
- log日誌:
MyAppUtils: integer=0,當前線程mainThread = main
MyAppUtils: integer=1,當前線程io = RxCachedThreadScheduler-3
MyAppUtils: integer=2,當前線程newThread = RxNewThreadScheduler-1
MyAppUtils: integer=3,當前線程computation = RxComputationThreadPool-1
MyAppUtils: integer=4,當前線程single = RxSingleScheduler-1
MyAppUtils: integer=5,當前線程mainThread = main