一、前言
閱讀本文前,建議詳細閱讀并掌握什么是觀察者模式。
https://github.com/ReactiveX/RxJava
https://github.com/ReactiveX/RxAndroid
RxJava是ReactiveX的一種Java的實現形式,擁有三大部分
- 觀察者模式,即定義對象間一種一對多的依賴關系,當一個對象改變狀態時,則所有依賴它的對象都會被改變。
- Iterator模式,即迭代流式編程模式。
- 函數式編程模式,即提供一系列函數樣式的方法供快速開發。
首先RxAndroid基于RxJava,RxAndroid結合Android添加了很少的類,讓我們在Android更方便和簡單的使用RxJava。RxJava和RxAndroid已經來到了3.0+版本
RxJava核心思想:觀察者模式 + 異步 來處理事件
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
二、基本用法
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("one");
emitter.onNext("two");
//emitter.onComplete();
emitter.onError(new Throwable("error"));
}
});
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d("yink","onSubscribe ...");
}
@Override
public void onNext(@NonNull String s) {
Log.d("yink","onNext = " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.d("yink","onError ... = " + e);
}
@Override
public void onComplete() {
Log.d("yink","onComplete ...");
}
};
observable.subscribeOn(Schedulers.newThread());
observable.observeOn(AndroidSchedulers.mainThread());
Log.d("yink","subscribe ...");
observable.subscribe(observer);
首先,RxJava基于觀察者模式,所以它的結構很簡單,無非觀察者模式三步驟:
-
Observable
被觀察者,ObservableEmitter為被觀察者的幾個事件。(onComplete和onError唯一且互斥) -
Observer
觀察者,觀察幾個方法 -
observable.subscribe(observer)
提交觀察者到被觀察者
其次,RxJava還額外實現了線程調度,即控制觀察者和被觀察者的代碼在哪個線程執行:
-
observable.subscribeOn(Schedulers.newThread());
設置被觀察者開啟新線程來調度 -
observable.observeOn(AndroidSchedulers.mainThread());
設置觀察者在主線程調度
所以被觀察者中我們就可以做一些耗時操作,然后ObservableEmitter通知到觀察者,觀察者中可以刷新UI等操作。
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: subscribe ...
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onSubscribe ...
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onNext = one
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onNext = two
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onError ... = java.lang.Throwable: error
整體看來RxJava是為了讓我們更加優雅的異步,異步指定線程方便,過程好控制,還可多個觀察者,指定不同線程,這樣異步真的太方便了。
三、詳細介紹
現在我們知道RxJava大體框架,觀察者模式+異步。下面我們來看詳細介紹。詳細介紹分為下面幾個部分:
-
Observer
觀察者的各種擴展寫法 -
Observable
被觀察者的各種拓展寫法 - 線程調度,指定線程操作相關
3.1、觀察者Observer
觀察者的擴展寫法就比較簡單
public final Disposable subscribe()
void subscribe(@NonNull Observer<? super T> observer);
public final Disposable subscribe(@NonNull Consumer<? super T> onNext)
public final Disposable subscribe(@NonNull Consumer<? super T> onNext,
@NonNull Consumer<? super Throwable> onError)
public final Disposable subscribe(@NonNull Consumer<? super T> onNext,
@NonNull Consumer<? super Throwable> onError,
@NonNull Action onComplete)
public final Disposable subscribe(@NonNull Action onComplete) {
public final Completable doOnSubscribe(@NonNull Consumer<? super Disposable> onSubscribe) {
public final void blockingSubscribe(@NonNull Action onComplete) {
...
- 可以看到我們提交觀察者時,觀察者的幾個變種
- subscribe() 實際提交的是一個Functions.emptyConsumer()
- onNext事件:Consumer<? super T>
- onError事件:Consumer<? super Throwable>
- onComplete事件:Action
- Observer<? super T> observer:多種繼承自Observer的類也可以
所以,我們在監聽上,就可以簡單只監聽部分事件。例如
Observable.just("one").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
}
});
這個例子就提交了兩個觀察者。一個觀察者只監聽onNext事件,一個觀察者只監聽onError事件。當然你也可以只提交一個觀察者。源碼如下,很好理解,我隨便點了一個subscribe的實現
public final Disposable subscribe(@NonNull Consumer<? super T> onNext, @NonNull Consumer<? super Throwable> onError,
...
LambdaObserver<T> ls = new LambdaObserver<>(onNext, onError, onComplete, Functions.emptyConsumer());
subscribe(ls);
return ls;
}
public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete,
Consumer<? super Disposable> onSubscribe) {
super();
this.onNext = onNext;
this.onError = onError;
this.onComplete = onComplete;
this.onSubscribe = onSubscribe;
}
@Override
public void onNext(T t) {
if (!isDisposed()) {
try {
onNext.accept(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
get().dispose();
onError(e);
}
}
}
3.2、被觀察者Observable
Observable是被觀察者產生的地方,分下面幾個方面介紹:
- Observable的創建
- Observable操作符歸類
- Observable擴展:Flowable、Maybe、Single、Completable
3.2.1、Observable的創建
事件產生理解上很簡單,就是創建被觀察者,我們以just的為例,看看它的整體思路
Observable.just("a","b").subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d("yink","onSubscribe ...");
}
@Override
public void onNext(@NonNull String s) {
Log.d("yink","onNext = " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.d("yink","onError ... = " + e);
}
@Override
public void onComplete() {
Log.d("yink","onComplete ...");
}
});
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onSubscribe ...
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onNext = a
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onNext = b
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onComplete ...
將對象或者對象集合轉換為一個會發射這些對象的Observable
just用法很簡單,直接把數組以onNext事件傳遞,傳遞完后 調用onComplete事件
我們接著來看看just方法的實現,篇幅原因,我省去了一些代碼。
public static <T> Observable<T> just(@NonNull T item1, @NonNull T item2) {
...
return fromArray(item1, item2);
}
public static <T> Observable<T> fromArray(@NonNull T... items) {
...
return RxJavaPlugins.onAssembly(new ObservableFromArray<>(items));
}
public final class ObservableFromArray<T> extends Observable<T> {
final T[] array;
public ObservableFromArray(T[] array) {
this.array = array;
}
@Override
public void subscribeActual(Observer<? super T> observer) {
FromArrayDisposable<T> d = new FromArrayDisposable<>(observer, array);
observer.onSubscribe(d);
if (d.fusionMode) {
return;
}
d.run();
}
static final class FromArrayDisposable<T> extends BasicQueueDisposable<T> {
....
FromArrayDisposable(Observer<? super T> actual, T[] array) {
this.downstream = actual;
this.array = array;
}
...
void run() {
T[] a = array;
int n = a.length;
for (int i = 0; i < n && !isDisposed(); i++) {
T value = a[i];
if (value == null) {
downstream.onError(new NullPointerException("The element at index " + i + " is null"));
return;
}
downstream.onNext(value);
}
if (!isDisposed()) {
downstream.onComplete();
}
}
}
}
- 可以看到調用流程也很簡單,把數組挨個調用就可以了,最后發出onComplete事件
- 事件的產生代碼都極其類似,最后定位實現都會定位到類似
ObservableFromArray.java
這樣的實現 - 事件產生實現的代碼路徑在“/RxJava-3.x/src/main/java/io/reactivex/rxjava3/internal/operators/observable/**”,此路徑下有很多種實現,包括from系列,just,create,error,timer等等,只是RxJava源碼為我們默認添加的一些實現。
- 創建觀察者思想都類似,就不一一詳述了,簡單介紹如下:
用法 | 簡單介紹 |
---|---|
create | 通過調用觀察者的方法從頭創建一個Observable |
frome | 封裝Iterable、Array、Callable、Action、Runnable、Future,以執行為核心,調用封裝的類型的內部事件。將其它的對象或數據結構轉換為Observable |
targetType.from{sourceType}() |
|
just | 將對象或者對象集合轉換為一個會發射這些對象的Observable |
defer | 普通observable創建對象時就確定了參數,defer則是我們提交觀察者時才去創建被觀察者和參數,相當于一個懶加載,在觀察者訂閱之前不創建這個Observable,為每一個觀察者創建一個新的Observable |
range | rang(0,10)直接生成0-10事件,創建發射指定范圍的整數序列的Observable |
interval | interval(1, TimeUnit.SECONDS);周期性生成一個無限的、永遠增長的數(長整型) |
timer | Observable.timer(5, TimeUnit.MINUTES)延時五分鐘發送事件 |
empty | 創建一個不發射任何數據但是正常終止的Observable,只調用一個onCompleted方法 |
never | 創建一個什么事件都不發送的被觀察者 |
error | 發送error事件 |
3.2.2、ObservableObservable操作符歸類
Rxjava提供的操作符真的蠻多的。主要分為下面幾個大類
- 直接創建一個Observable(創建操作)
- 組合多個Observable(組合操作)
- 對Observable發射的數據執行變換操作(變換操作)
- 從Observable發射的數據中取特定的值(過濾操作)
- 轉發Observable的部分值(條件/布爾/過濾操作)
- 對Observable發射的數據序列求值(算術/聚合操作)
這段歸類描述引用自知乎的一個回答,Rxjava、rxandroid中的操作,這里我將其制成表格,供大家查閱使用,上面有創建操作符表格,所以下面是省略這部分。
變換操作
用法 | 簡單介紹 |
---|---|
Buffer | 緩存,可以簡單的理解為緩存,它定期從Observable收集數據到一個集合,然后把這些數據集合打包發射,而不是一次發射一個 |
FlatMap | 扁平映射,將Observable發射的數據變換為Observables集合,然后將這些Observable發射的數據平坦化的放進一個單獨的Observable,可以認為是一個將嵌套的數據結構展開的過程。 |
GroupBy | 分組,將原來的Observable分拆為Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據 |
Map | 映射,通過對序列的每一項都應用一個函數變換Observable發射的數據,實質是對序列中的每一項執行一個函數,函數的參數就是這個數據項 |
Scan | 掃描,對Observable發射的每一項數據應用一個函數,然后按順序依次發射這些值 |
Window | 窗口,定期將來自Observable的數據分拆成一些Observable窗口,然后發射這些窗口,而不是每次發射一項。類似于Buffer,但Buffer發射的是數據,Window發射的是Observable,每一個Observable發射原始Observable的數據的一個子集 |
lift | 把事件處理一次后再發送到Observer |
過濾操作
用法 | 簡單介紹 |
---|---|
Debounce | 只有在空閑了一段時間后才發射數據,通俗的說,就是如果一段時間沒有操作,就執行一次操作 |
Distinct | 去重,過濾掉重復數據項 |
ElementAt | 取值,取特定位置的數據項 |
Filter | 過濾,過濾掉沒有通過謂詞測試的數據項,只發射通過測試的 |
First | 首項,只發射滿足條件的第一條數據 |
IgnoreElements | 忽略所有的數據,只保留終止通知(onError或onCompleted) |
Last | 末項,只發射最后一條數據 |
Sample | 取樣,定期發射最新的數據,等于是數據抽樣,有的實現里叫ThrottleFirst |
Skip | 跳過前面的若干項數據 |
SkipLast | 跳過后面的若干項數據 |
Take | 只保留前面的若干項數據 |
TakeLast | 只保留后面的若干項數據 |
組合操作
用法 | 簡單介紹 |
---|---|
And/Then/When | 通過模式(And條件)和計劃(Then次序)組合兩個或多個Observable發射的數據集 |
CombineLatest | 當兩個Observables中的任何一個發射了一個數據時,通過一個指定的函數組合每個Observable發射的最新數據(一共兩個數據),然后發射這個函數的結果 |
Join | 無論何時,如果一個Observable發射了一個數據項,只要在另一個Observable發射的數據項定義的時間窗口內,就將兩個Observable發射的數據合并發射 |
Merge | 將兩個Observable發射的數據組合并成一個 |
StartWith | 在發射原來的Observable的數據序列之前,先發射一個指定的數據序列或數據項 |
Switch | 將一個發射Observable序列的Observable轉換為這樣一個Observable:它逐個發射那些Observable最近發射的數據 |
Zip | 打包,使用一個指定的函數將多個Observable發射的數據組合在一起,然后將這個函數的結果作為單項數據發射 |
錯誤處理
這些操作符用于從錯誤通知中恢復
用法 | 簡單介紹 |
---|---|
Catch | 捕獲,繼續序列操作,將錯誤替換為正常的數據,從onError通知中恢復 |
Retry | 重試,如果Observable發射了一個錯誤通知,重新訂閱它,期待它正常終止 |
輔助操作
用法 | 簡單介紹 |
---|---|
Delay | 延遲一段時間發射結果數據 |
Do | 注冊一個動作占用一些Observable的生命周期事件,相當于Mock某個操作 |
Materialize/Dematerialize | 將發射的數據和通知都當做數據發射,或者反過來 |
ObserveOn | 指定觀察者觀察Observable的調度程序(工作線程) |
Serialize | 強制Observable按次序發射數據并且功能是有效的 |
Subscribe | 收到Observable發射的數據和通知后執行的操作 |
SubscribeOn | 指定Observable應該在哪個調度程序上執行 |
TimeInterval | 將一個Observable轉換為發射兩個數據之間所耗費時間的Observable |
Timeout | 添加超時機制,如果過了指定的一段時間沒有發射數據,就發射一個錯誤通知 |
Timestamp | 給Observable發射的每個數據項添加一個時間戳 |
Using | 創建一個只在Observable的生命周期內存在的一次性資源 |
條件和布爾操作
用法 | 簡單介紹 |
---|---|
All | 判斷Observable發射的所有的數據項是否都滿足某個條件 |
Amb | 給定多個Observable,只讓第一個發射數據的Observable發射全部數據 |
Contains | 判斷Observable是否會發射一個指定的數據項 |
DefaultIfEmpty | 發射來自原始Observable的數據,如果原始Observable沒有發射數據,就發射一個默認數據 |
SequenceEqual | 判斷兩個Observable是否按相同的數據序列 |
SkipUntil | 丟棄原始Observable發射的數據,直到第二個Observable發射了一個數據,然后發射原始Observable的剩余數據 |
SkipWhile | 丟棄原始Observable發射的數據,直到一個特定的條件為假,然后發射原始Observable剩余的數據 |
TakeUntil | 發射來自原始Observable的數據,直到第二個Observable發射了一個數據或一個通知 |
TakeWhile | 發射原始Observable的數據,直到一個特定的條件為真,然后跳過剩余的數據 |
算術和聚合操作
用法 | 簡單介紹 |
---|---|
Average | 計算Observable發射的數據序列的平均值,然后發射這個結果 |
Concat | 不交錯的連接多個Observable的數據 |
Count | 計算Observable發射的數據個數,然后發射這個結果 |
Max | 計算并發射數據序列的最大值 |
Min | 計算并發射數據序列的最小值 |
Reduce | 按順序對數據序列的每一個應用某個函數,然后返回這個值 |
Sum | 計算并發射數據序列的和 |
連接操作
用法 | 簡單介紹 |
---|---|
Connect | 指示一個可連接的Observable開始發射數據給訂閱者 |
Publish | 將一個普通的Observable轉換為可連接的 |
RefCount | 使一個可連接的Observable表現得像一個普通的Observable |
Replay | 確保所有的觀察者收到同樣的數據序列,即使他們在Observable開始發射數據之后才訂閱 |
轉換操作
用法 | 簡單介紹 |
---|---|
To | 將Observable轉換為其它的對象或數據結構 |
Blocking | 阻塞Observable的操作符 |
這幾個表格的目的是方便大家查閱,我們不需要一口氣學習所有操作符,知其思想即可。這些操作符目的加工Observable
由于篇幅原因這里只舉一個map例子,上面所有操作符都很容易上手使用,就不過多闡述。
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 "map add " + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("yink", s);
}
});
2020-03-24 14:59:30.518 8467-8467/com.example.demo D/yink: map add 1
2020-03-24 14:59:30.518 8467-8467/com.example.demo D/yink: map add 2
2020-03-24 14:59:30.518 8467-8467/com.example.demo D/yink: map add 3
自定義操作符
自定義操作符有兩個方向:
- 對Observable被觀察者中的數據動刀,讓數據轉換一次,最后再發送到觀察者。
- 對Observable被觀察者直接動刀,轉換一次被觀察者
1、實現ObservableOperator接口,轉換數據
@FunctionalInterface
public interface ObservableOperator<@NonNull Downstream, @NonNull Upstream> {
@NonNull
Observer<? super Upstream> apply(@NonNull Observer<? super Downstream> observer) throws Throwable;
}
Observable.just("1","2")
.lift(new YourClass<String>())
2、實現ObservableOperator
public interface ObservableTransformer<Upstream, Downstream> {
@NonNull
ObservableSource<Downstream> apply(@NonNull Observable<Upstream> upstream);
}
Observable.just("1","2")
.compose(new YourTransformer())
.subscribe...
3.2.3、Observable擴展
Flowable、Maybe、Single、Completable
Flowable
Flowable為了解決背壓的問題而存在。直接上例子:
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
for(int j = 0; j <= 100; j++){
e.onNext(j);
Log.i("yink"," send id = " + j);
try{
Thread.sleep(50);
}catch (Exception ex){
}
}
}
}, BackpressureStrategy.MISSING)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE); //觀察者設置接收事件的數量,如果不設置接收不到事件
}
@Override
public void onNext(Integer integer) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("yink","onNext = " + integer);
}
@Override
public void onError(Throwable t) {
Log.e("yink","onError = " + t.toString());
}
@Override
public void onComplete() {
Log.e("yink","onComplete");
}
});
- 背壓:被觀察者發送事件的速度大于觀察者接收的速度時,觀察者內部是創建一個無限大的緩存來暫存沒有處理的事件。如果事件太多會導致OOM。
- Flowable提供了幾種方式來避免無限放大的緩存
- Flowable 在使用上并無太大差別,多了一個BackpressureStrategy參數,必須指定接收事件數量
- Flowable 緩存池默認大小是128
- BackpressureStrategy參數就是Flowable設置在背壓發生時處理的方式,參數類型如下:
public enum BackpressureStrategy {
MISSING,
ERROR,
BUFFER,
DROP,
LATEST
}
類型 | 簡單介紹 |
---|---|
MISSING | 不采取任何背壓策略(既不丟棄,也不緩存),超出隊列大小會拋出onError事件,不影響事件發送,拋出MissingBackpressureException: Queue is full?! |
ERROR | 萬一下游跟不上,拋出MissingBackpressureException: create: could not emit value due to lack of requests |
BUFFER | 緩存所有 |
DROP | 下游處理跟不上,刪除最新 |
LATEST | 下游處理跟不上,只保留最新 |
Single
Single,用法如其名,它只有onSuccess和onError事件,只發送一次事件。例子如下比較簡單:
Single.create(new SingleOnSubscribe<String>() {
@Override
public void subscribe(@NonNull SingleEmitter<String> e) throws Exception {
e.onSuccess("1");
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
Log.d("yink","s = " + s.toString());
}
});
public interface SingleEmitter<@NonNull T> {
void onSuccess(@NonNull T t);
void onError(@NonNull Throwable t);
void setDisposable(@Nullable Disposable d);
void setCancellable(@Nullable Cancellable c);
boolean isDisposed();
boolean tryOnError(@NonNull Throwable t);
}
Completable
Completable不發送任何數據,發送onComplete和onError,用法也比較簡單,下面例子就是,線程執行完了,接著可以做別的。因為線程執行時也不用發出什么事件,或者發送值。
Completable還支持toXXX,轉換成Flowable/Single/Maybe/Observable
Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(@NonNull CompletableEmitter emitter) throws Exception {
try{
Thread.sleep(50);
}catch (Exception ex){
}
}
}).andThen(Observable.range(1, 10))
.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.d("yink","integer = " + integer);
}
});
public interface CompletableEmitter {
void onComplete();
void onError(@NonNull Throwable t);
void setDisposable(@Nullable Disposable d);
void setCancellable(@Nullable Cancellable c);
boolean isDisposed();
}
Maybe
Maybe可以理解為Single和Completable的結合。看事件就理解了,Maybe只能傳一次值onSuccess,然后支持onComplete和onError事件。
Maybe.create(new MaybeOnSubscribe<String>() {
@Override
public void subscribe(@NonNull MaybeEmitter<String> e) throws Exception {
e.onSuccess("testA");
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
Log.d("yink", " s = " + s);
}
});
public interface MaybeEmitter<@NonNull T> {
void onSuccess(@NonNull T t);
void onError(@NonNull Throwable t);
void onComplete();
void setDisposable(@Nullable Disposable d);
void setCancellable(@Nullable Cancellable c);
boolean isDisposed();
boolean tryOnError(@NonNull Throwable t);
}
所以Rxjava提供五種被觀察者寫法:Observable、Flowable、Maybe、Single、Completable。可以方便我們再合適的地方用合適的類,寫出更優美的代碼。
3.3、線程調度
此小結為RxJava最騷的地方,正是因為RxJava在觀察者模式上增加了線程調度,所以讓異步變得如此優美。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
Log.e("yink", "Observable call: " + Thread.currentThread().getName());
emitter.onNext("one");
emitter.onNext("two");
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.e("yink", "Observer call: " + Thread.currentThread().getName());
Log.d("yink","s = " + s);
}
});
2020-03-25 09:31:38.388 29612-29724/com.example.demo E/yink: Observable call: RxNewThreadScheduler-1
2020-03-25 09:31:38.417 29612-29612/com.example.demo E/yink: Observer call: main
2020-03-25 09:31:38.417 29612-29612/com.example.demo D/yink: s = one
2020-03-25 09:31:38.417 29612-29612/com.example.demo E/yink: Observer call: main
2020-03-25 09:31:38.417 29612-29612/com.example.demo D/yink: s = two
方法 | 簡單介紹 |
---|---|
Schedulers.io() | 用于IO密集型的操作,線程緩存(有空閑則復用,否則無限增加) |
Schedulers.newThread() | 每次創建一個新線程,不具有緩存 |
Schedulers.single() | 單線程,先進先出 |
Schedulers.computation() | cpu密集型計算任務,具有固定的線程池,大小為CPU核數,不可以用于IO操作,因為IO操作的等待時間會浪費cpu |
Schedulers.trampoline() | 立即執行當前添加任務A,若有一個B任務正在執行,則暫停B,執行完A后再接著執行B |
Schedulers.from(Executor) | 提供帶入線程池的方式 |
AndroidSchedulers.mainThread() | RxAndroid擴展,Android中UI線程中執行 |
AndroidSchedulers.from(Looper) | RxAndroid擴展,Looper當前循環線程執行 |
RxJava/RxAndroid默認給我們線程調度方式基本涵蓋了我們絕大部分會使用的情況。
四、RxAndroid
RxAndroid中的代碼很少,它擴展的意義在于方便我們結合Android特性,在UI線程中調度。或者結合Handler調度。舉兩個例子
public class ReactiveFragment extends Fragment {//在UI線程中的例子
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Observable.just("one", "two", "three", "four", "five")
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(/* an Observer */);
}
new Thread(new Runnable() {//在其他線程中的例子
@Override
public void run() {
final Handler handler = new Handler(); //綁定到這個線程的Handler
Observable.just("one", "two", "three", "four", "five")
.subscribeOn(Schedulers.newThread())
.observeOn(HandlerScheduler.from(handler))
.subscribe(/* an Observer */)
}
}, "custom-thread-1").start();
五、寫在最后
到此RxJava和RxAndroid介紹的差不多了。本文主要目的是全方位的介紹一下RxJava,主要拆分成:被觀察者 + 觀察者 + 異步,分部分來講解。來達到對RxJava有一個整體上,不光是用法,還有思想上的理解。希望本文對你有所幫助。有啥對或者不對的地方,歡迎交流,指正。