目錄
1. Rxjava簡介
Rxjava是什么?簡單來說就是一個可以實現異步操作的庫。如果是沒有接觸過Rxjava可以直接使用RxJava2.0,并不會有任何問題。如果是已經在用RxJava1.0或者項目當中已經使用了RxJava1.0那就只能一條路走到黑了。我就是屬于后者。
相比于AsyncTask、Handler,RxJava代碼更顯得優雅簡介,調理清晰,隨著產品邏輯復雜度的增加,也依然可以使得代碼非常簡介。rxjava的異步實現是通過一種擴展的觀察者模式來實現的,先來簡單了解一下觀察者模式。
1.1 觀察者模式
觀察者模
:定義對象間的一種一對多的依賴關系,使得每當一個對象改變狀態時,所有依賴于它的對象都會得到通知并被自動更新。
觸發場景
- 事件關聯場景,需要注意關聯行為是不可拆分的,不是簡單地“組合”關系。
- 事件多級觸發的場景。
- 跨系統的消息處理,如消息隊列、事件總線等處理機制。
在整個觀察者模式中一共有四個角色:Subject(抽象主題、抽象被觀察者)、Concrete Subject(具體主題、具體被觀察者)、Observer(抽象觀察者)以及ConcreteObserver(具體觀察者)。四個角色關系如下:
- Subject(抽象主題、抽象被觀察者):抽象主題把所有被觀察者對象保存到一個集合當中,并提供一個接口,可以增加、刪除和更新觀察者對象。
- ConcreteSubject(具體主題、具體被觀察者):將有關狀態存入具體觀察者對象,在具體主題的內部狀態發生時改變,給所有注冊過的觀察者發出通知。
- Observer(抽象觀察者):觀察者的抽象類,定義更新接口,使得被觀察者可以在得到主題的時候更新自己。
- ConcreteObserver(具體觀察者):實現抽象觀察者定義的更新接口,以便主題的狀態發生變化時更新自身狀態。
我們用一個具體的場景來體會一下。
說,兩國交戰,有一只隊弓箭手A在要進行埋伏。弓箭手部隊拆分為4隊A1、A2、A3,有指揮者
發布命令,當收到命令時所有小隊進行射擊。這個時候指揮者
就是被觀察者
而每一隊弓箭手就是觀察者
,代碼實現如下。
被觀察者代碼如下
/**
* 定義被觀察者抽象類
*/
public abstract class Subject<T> {
//創建觀察者集合
List<Observer> mList = new ArrayList<Observer>();
//添加觀察者
public void add(Observer observer) {
mList.add(observer);
}
//刪除觀察者
public void remove(Observer observer) {
if(mList!=null&&mList.contains(observer)){
mList.remove(observer);
}
}
//更新
public abstract void notifyObserver(T t);
}
/**
* 被觀察者具體實現
*/
public class ConcreteSubject<T> extends Subject<T> {
@Override
public void notifyObserver(T t) {
for(Observer observer:mList){
observer.update(t);
}
}
}
觀察者代碼如下
/**
* 觀察者抽象接口
*/
public interface Observer<T> {
void update(T t);
}
/**
* 觀察者具體實現
*/
public abstract class ConcreteObserver<T> implements Observer<T> {
String name;
public ConcreteObserver(String name) {
this.name = name;
}
public String getName(){
return name;
}
}
這里我的觀察者是一個抽象類,實現方式類似于Rxjava的實現方式。
Main當中的代碼調用
//update類具體實現創建observer1、observer2、observer3三個觀察者
Observer<String> observer1 = new ConcreteObserver<String>("弓箭手A1隊") {
@Override
public void update(String s) {
Log.d("Observer1", getName() + "收到命令:" + s);
}
};
Observer<String> observer2 = new ConcreteObserver<String>("弓箭手A2隊") {
@Override
public void update(String s) {
Log.d("Observer2", getName() + "收到命令:" + s);
}
};
Observer<String> observer3 = new ConcreteObserver<String>("弓箭手A3隊") {
@Override
public void update(String s) {
Log.d("Observer3", getName() + "收到命令:" + s);
}
};
//設置被觀察者與觀察者之間關聯
Subject<String> subject = new ConcreteSubject<String>();
subject.add(observer1);
subject.add(observer2);
subject.add(observer3);
//被觀察者發送信息
subject.notifyObserver("射殺騎白馬者!!");
打印日志
D/Observer1: 弓箭手A1隊收到命令:射殺騎白馬者!!
D/Observer2: 弓箭手A2隊收到命令:射殺騎白馬者!!
D/Observer3: 弓箭手A3隊收到命令:射殺騎白馬者!!
1.2 Rxjava中的觀察者模式
在Rxjava當中有四個基本概念,除了觀察者Observer/Subscriber
和被觀察者Observable
之外,ha存在訂閱subscribe
以及事件
。
被觀察者Observable
與觀察者Observer/Subscriber
產生關聯的方法就是subscribe
,即事件訂閱,當開始訂閱時,被觀察者Observable
便開始發送事件
。對于事件
,Rxjava定義了三種事件類型:
- onNext():普通的事件,用于一般的事件發送。
- onCompleted(): 完成事件,當不再有新的onNext()事件時調用onCompleted方法作為整個事件隊列結束的標志,在一個事件隊列當中可以有多個onCompleted方法,但是只能觸發一次,一旦觸發之后,后續的事件會繼續發送,但是觀察者將不會接受事件。
- onError(): 事件隊列異常。在事件處理過程中出現異常時,onError()會被觸發,同事隊列自動終止,與
onCompleted()
方法相同,onError事件也可以存在多個,但是只會觸發一次。
最為關鍵的是
onComplete
和onError
存在互斥的關系, 兩個方法可以同時存在于事件隊列當中,但是一旦觸發其中一個方法之后,后續將不再接收事件。
2.基本實現
RxJava的實現非常簡單
首先要在Android studio中配置gradle
implementation 'io.reactivex:rxjava:1.1.6'
implementation 'io.reactivex:rxandroid:1.2.1'
RxAndroid是RxJava在Android平臺的一些擴展,包含了一些能夠簡化Android開發的工具。(implementation與compile用法基本相同,有興趣的可以去了解一下兩者的差別)
2.1 創建觀察者
觀察者Observer
決定了事件觸發的時候將有怎樣的行為。
Observer<String> observer = new Observer<String>() {
//被觀察者調用onCompleted時觸發
@Override
public void onCompleted() {
Log.d(TAG,"onCompleted");
}
//被觀察者調用onError時觸發
@Override
public void onError(Throwable e) {
Log.d(TAG,"onError");
}
//被觀察者調用onNext時觸發
@Override
public void onNext(String s) {
Log.d(TAG,"onNext");
}
};
另外一個觀察者就是Subscriber
,而實際上在調用subscribe
方法訂閱的時候也是把Observer
轉換為了Subscriber
處理的,后文我們會在RxJava的代碼中提到,先來看一看Subscriber
的實現,與Observer
基本一致。
Subscriber<String> subscriber = new Subscriber<String>() {
//新增onStart方法,用來做一些初始化操作
@Override
public void onStart() {
super.onStart();
}
@Override
public void onCompleted() {
Log.d(TAG,"onCompleted");
}
@Override
public void onError(Throwable e) {
Log.d(TAG,"onError");
}
@Override
public void onNext(String s) {
Log.d(TAG,"onNext");
}
};
這里新增加了
onStart
方法,這個方法會在事件開始發送前調用,實際應用中我們可以在這個方法當中做一些初始化的操作,但是這個方法一般只會在subscribe發生的線程執行(使用doOnSubscribe()方法可以改變準備線程)。另一個不同就是Subscriber實現了另一個接口Subscription,它里面提供了兩個方法unsubscribe()和isUnsubscribed():
- unsubscribe:用于取消訂閱,因為RxJava當中的操作可能會引起內存泄漏,在合適的地方調用該方法可以避免這個問題。
- isUnsubscribed:用于判斷訂閱是否被取消。
2.2 創建被觀察者
它決定什么時候觸發事件以及觸發怎樣的事件。RxJava提供了多種構建被觀察者的方式,也提供了很多特殊的被觀察者,這里介紹一些比較常用的方法。
使用create
創建被觀察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Log.d(TAG,"Observable Test");
//定義事件隊列
subscriber.onNext("aaaa");
subscriber.onCompleted();
}
});
使用create( )創建Observable最基本的創建方式。可以看到,這里傳入了一個 Observable.OnSubscribe對象作為參數,當 Observable被訂閱的時候,Observable.OnSubscribe的call()方法會自動被調用,事件序列就會依照設定依次觸發。這樣,由被觀察者調用了觀察者的回調方法,就實現了由被觀察者向觀察者的事件傳遞,即觀察者模式。
除了create
方法之外,還存在其他的常用的構建方式。
just()
使用just( )
,將為你創建一個Observable并自動為你調用onNext( )發射數據。通過just( )方式 直接觸發onNext(),just中傳遞的參數將直接在Observer的onNext()方法中接收到。
Observable<String> observable = Observable.just("hello");
observable.subscribe(subscriber);
輸出log
D/MainActivity: onNext
D/MainActivity: onCompleted
from()
from()
方法將傳入的數組
或Iterable
拆分成具體對象后,自動調用onNext
方法依次發送,再發送結束后發送onCompleted
結束整個事件。
//定義要發送的事件集合
List<String> mList = new ArrayList<String>();
mList.add("aaaa");
mList.add("bbbb");
mList.add("cccc");
mList.add("dddd");
//定義Observable
Observable<String> observable = Observable.from(mList);
//進行訂閱,開始發送事件
observable.subscribe(subscriber);
D/MainActivity: onNextaaaa
D/MainActivity: onNextbbbb
D/MainActivity: onNextcccc
D/MainActivity: onNextdddd
D/MainActivity: onCompleted
defer()
通過defer()
方法創建Observable,當觀察者訂閱時,才創建Observable,并且針對每個觀察者創建都是一個新的Observable。以何種方式創建這個Observable對象,當滿足回調條件后,就會進行相應的回調。還是通過代碼來看。
//定義一個被觀察者
Observable<String> observable = Observable.defer(new Func0<Observable<String>>() {
@Override
public Observable<String> call() {
Observable<String> mObservable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("事件訂閱開始");
}
});
return mObservable;
}
});
//訂閱事件1,沒產生一個訂閱就會生成一個新的observable對象
observable.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG,"觀察者2訂閱事件 "+s);
}
});
//訂閱事件2,沒產生一個訂閱就會生成一個新的observable對象
observable.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG,"觀察者1訂閱事件 "+s);
}
});
打印輸出運行結果
D/MainActivity: 觀察者2訂閱事件 事件訂閱開始
D/MainActivity: 觀察者1訂閱事件 事件訂閱開始
使用defer()
方法,每當產生新的訂閱事件時都會生成一個新的mObservable
對象。
這里用到了不完整定義的回調
Action
,它就相當于我們之前定義的subscriber,但是其只針對onNext
事件做處理,后續我們介紹subscribe()
時再詳細介紹。
interval()
創建一個按固定時間間隔發射整數序列的Observable,可用作定時器。即按照固定時長調用onNext()方法。
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
observable.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
Log.d(TAG,"訂閱時長為"+aLong);
}
});
輸出結果日志:
D/MainActivity: 訂閱時長為0
D/MainActivity: 訂閱時長為1
D/MainActivity: 訂閱時長為2
D/MainActivity: 訂閱時長為3
D/MainActivity: 訂閱時長為4
D/MainActivity: 訂閱時長為5
D/MainActivity: 訂閱時長為6
......
每隔一秒發送一個事件交給觀察者處理。
timer()
該方法可以在一定延遲之后發送特定事件。
//定義被觀察者,在2000毫秒后開始發送事件
Observable<Long> observable = Observable.timer(2000,TimeUnit.MILLISECONDS);
Subscriber<Long> subscriber = new Subscriber<Long>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Long aLong) {
Log.d(TAG,"收到事件啦");
}
};
Log.d(TAG,"開始訂閱發送事件");
observable.subscribe(subscriber);
輸出日志
16:09:38.524 D/MainActivity: 開始訂閱發送事件
16:09:40.524 D/MainActivity: 收到事件啦
可以看到在訂閱之后,過了2000毫秒observable
開始發送事件。
到這里我們創建了觀察者Observable
與觀察者Observer/Subscriber
,只到這一步我們會產生很多疑問:interval發送事件如何取消訂閱、上面提到的Action到底什么時候會用到,為什么Subscriber的start方法只能在默認線程調用等等問題。這個時候就該到我們的subscribe
登場了。
2.3 Subscribe訂閱
創建完Observable
與Observer/Subscriber
,使用subscribe
那我們整個訂閱過程就就完成了,在上面的代碼也有提到,整個調用方式如下
observable.subscribe(subscriber);
我們來簡單看一下subscribe()
方法的源碼。
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
subscriber.onStart();
observable.onSubscribe.call(subscriber);
return Subscription;
}
這里提出了關鍵的流程代碼,結合訂閱的調用過程我們分析整個訂閱流程。
- 首先是傳進來的兩個參數
Subscriber
和Observable
分別對應我們調用時的subscriber
和observable
。 - 訂閱開始后,首先執行的是
subscriber.onStart()
方法,也就是我們觀察者的onStart方法,這也就解釋了為什么onStart
方法只可以在默認線程當中執行,因為我們指定線程只可以指定observable所對應線程以及observable對應直屬下級Subscriber
(好吧這里又是一個坑,后文我們會做解釋)所在線程。 - 接下來調用observable當中的onSubscribe.call方法,我們的整個事件序列就定義在這里,調用call方法開始發送事件。
- 返回值
Subscription
,之前在介紹觀察者Subscriber
時我們有提到,Subscriber
實現了這個接口,用于提供解除訂閱以及判斷訂閱是否連接的方法,在訂閱完成之后返回Subscription
供外部調用。
不完整定義回調
從上圖可以看出,subscribe方法的參數除了
Subscriber
和Observer
之外,還有Action類,這就是將要介紹的不完整定義回調
。
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("aaaaa");
subscriber.onError(new NullPointerException());
}
});
//只對事件序列中的onNext做出響應
Action1<String> action1 = new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG,"action1--->onNext "+s);
}
};
//只對事件序列中的onError做出響應
Action1<Throwable> action11 = new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Log.d(TAG,"action11--->onError "+throwable.getMessage());
}
};
//只對事件序列中的onCompleted做出響應
Action0 action0 = new Action0() {
@Override
public void call() {
Log.d(TAG,"action11--->onCompleted ");
}
};
//訂閱事件,只處理onNext事件
observable.subscribe(action1);
//訂閱事件,只處理onNext和onError事件
observable.subscribe(action1,action11);
//訂閱事件,處理onNext、onError和onCompleted事件
observable.subscribe(action1,action11,action0);
2.4 RxJava鏈式調用
在實際應用中,我們可以采用鏈式調用的方式把上述步驟串聯起來,從而使得代碼結構更加簡潔,優雅。
//定義將要發射的數組
String[] strs = {"1", "2", "3", "4", "5"};
//from操作符可以把數組當中的數據逐條發送出去
Observable.from(strs)
//調用flatMap操作符把String類型轉換為新的Observable<String>并開始發送事件后文會進行介紹。
.flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
Log.d("testRX---map",s);
//需要把String類型轉換成的Observable對象
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("test");
}
});
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
//處理完成事件
}
@Override
public void onError(Throwable e) {
//處理error事件
}
@Override
public void onNext(String s) {
//處理普通的onNext事件
}
});
在這個例子中用到了變換操作符flatMap
,在實際應用中也會經常用到,下面我們詳細介紹一下。
3. 變換操作符
變換操作符的作用是對Observable發射的數據按照一定規則做一些變換操作,然后將變換后的數據發射出去。變換操作符有map,flatMap,switchMap,flatMapIterable,buffer,groupBy等。
map
map操作符就是通過制定一個Func1
對象,將原Observable
對象轉換為另一個Observable對象并發射。
//定義初始事件序列數組
Integer[] ints = {1, 2, 3};
//調用from逐個發射數據
//map方法把Intger類型轉換為String類型
Observable.from(ints).map(new Func1<Integer, String>() {
@Override
public String call(Integer i) {
//對Integer數據進行處理,轉換成String類型返回
return i + "號玩家";
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG,s+"加入游戲");
}
});
運行輸出結果:
D/MainActivity: 1號玩家加入游戲
D/MainActivity: 2號玩家加入游戲
D/MainActivity: 3號玩家加入游戲
這里就比較有意思了,map方法怎么就把一種數據類型轉換成了另一種數據類型呢
我們看一下map
的源碼
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return lift(new OperatorMap<T, R>(func));
}
//這里新建了一個Operator對象,核心功能代碼如下
public final class OperatorMap<T, R> implements Operator<R, T> {
final Func1<? super T, ? extends R> transformer;
public OperatorMap(Func1<? super T, ? extends R> transformer) {
this.transformer = transformer;
}
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
return parent;
}
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
這里新建一個newSubscriber
并與原observable
訂閱的Subscriber
關聯起來,left方法本身也返回一個新建的被觀察者newObservable
。由此變為,當產生事件訂閱時,實際上是newObservable
訂閱了事件,之后而通知原observable
開始發送事件,原observable
發送的事件發送向newSubscriber
,再發送給Subscriber
。
整個事件的流程變化如下:
flatMap
flatMap
也是用來做類型轉換,不同于map
的是,flatMap
轉換后得到的是一個Observable對象。代碼實現如下:
//interval方法創建Observable對象,每隔1秒發送一個事件
//經過flatMap方法變化,將long類型的事件變換為一個新的Observable對象發射出去
subscription = Observable.interval(1, TimeUnit.SECONDS).flatMap(new Func1<Long, Observable<String>>() {
@Override
public Observable<String> call(final Long aLong) {
return Observable.create(new Observable.OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> subscriber) {
Log.d("testRX---next","test"+aLong);
subscriber.onNext(aLong+"");
}
});
}
//定義Subscriber對變換后的事件進行接收
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError");
}
@Override
public void onNext(String s) {
Log.d(TAG, "onNext" + s);
}
});
打印輸出結果:
D/testRX---next: test0
D/MainActivity: onNext0
D/testRX---next: test1
D/MainActivity: onNext1
D/testRX---next: test2
D/MainActivity: onNext2
D/MainActivity: onNext3
......
flatMap
的原理比較復雜,我們還是通過源碼來分析
public final <R> Observable<R> flatMap(Func1<? super T, ? extends Observable<? extends R>> func) {
if (getClass() == ScalarSynchronousObservable.class) {
return ((ScalarSynchronousObservable<T>)this).scalarFlatMap(func);
}
return merge(map(func));
}
首先在這里它調用了map
方法,在前面我們分析過,map
方法會生成一個新的Observable對象,并改變事件的訂閱順序,接下來執行到merge方法,merge方法做了什么呢
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {
public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
this.parent = parent;
this.operator = operator;
}
@Override
public void call(Subscriber<? super R> o) {
Subscriber<? super T> st = hook.onLift(operator).call(o);
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
parent.call(st);
}
}
這里會把每一個創建出來的 Observable 發送的事件,都被匯入同一個 Observable ,這個 Observable 負責將這些事件統一交給 Subscriber 的回調方法。
buffer
buffer操作符將源Observable變換為一個新的Observable,這個新的Observable每次發射一組列表值而不是一個一個發射。和buffer操作類似的還有window操作符,只不過window操作符發射的是Observable而不是數據列表。
Observale.just(1,2,3,4,5,6).buffer(3).subscribe(new Action1<List<Integer>>() {
@Override
public void call(List<Integer> integers){
for(Integer integer:integers){
Log.d(TAG,"buffer"+integer);
}
Log.d(TAG,"---------");
}
});
輸出日志:
D/MainActivity: buffer1
D/MainActivity: buffer2
D/MainActivity: buffer3
D/MainActivity: ---------
D/MainActivity: buffer4
D/MainActivity: buffer5
D/MainActivity: buffer6
D/MainActivity: ---------
fliter
filter()操作符根據test()方法中,根據自己想過濾的數據加入相應的邏輯判斷,返回true則表示數據滿足條件,返回false則表示數據需要被過濾。最后過濾出的數據將加入到新的Observable對象中,方便傳遞給Observer想要的數據形式。
Observable.just(1,2,3,4,5,6).filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(@NonNull Integer integer){
if(integer > 3){
return true;
}
return false;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer){
Log.d(TAG,integer+"");
}
});
輸出結果
D/MainActivity: onSubscribe
D/MainActivity: onNext
D/MainActivity: Hello World!
D/MainActivity: 4
D/MainActivity: 5
D/MainActivity: 6
4. 線程調度
默認情況下,在哪個線程調subscribe()
,就會在哪個線程生產事件;在哪個線程生產事件,就在哪個線程消費事件。如果需要切換線程,則需要 Scheduler (調度器)
。
在RxJava 中,Scheduler,相當于線程控制器,RxJava 通過它來指定每一段代碼應該運行在什么樣的線程。RxJava 已經內置了幾個 Scheduler ,它們已經適合大多數的使用場景。
Scheduler 的 API
- Schedulers.immediate(): 直接在當前線程運行,相當于不指定線程。這是默認的 Scheduler。
- Schedulers.newThread(): 總是啟用新線程,并在新線程執行操作。
- Schedulers.io(): I/O 操作(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的 Scheduler。行為模式和 newThread() 差不多,區別在于 io() 的內部實現是用一個無數量上限的線程池,可以重用空閑的線程,因此多數情況下 io() 比 newThread() 更有效率。不要把計算工作放在 io() 中,可以避免創建不必要的線程。
- Schedulers.computation(): 計算所使用的 Scheduler。這個計算指的是 CPU 密集型計算,即不會被 I/O 等操作限制性能的操作,例如圖形的計算。這個 Scheduler 使用的固定的線程池,大小為 CPU 核數。不要把 I/O 操作放在 computation() 中,否則 I/O 操作的等待時間會浪費 CPU。
- Android 還有一個專用的
AndroidSchedulers.mainThread()
,它指定的操作將在 Android 主線程運行。
有了這幾個 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 兩個方法來對線程進行控制了。
- subscribeOn(): 指定Observable(被觀察者)所在的線程,或者叫做事件產生的線程。
-
observeOn(): 指定 Observer(觀察者)所運行在的線程,或者叫做事件消費的線程。
實例如下:
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
Log.d(TAG, Thread.currentThread().getName());
subscriber.onNext("aaaa");
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted");
Log.d(TAG, Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
Log.d(TAG, "onNext " + s);
}
});
輸出日志:
D/MainActivity: RxIoScheduler-2
D/MainActivity: onNext aaaa
D/MainActivity: onCompleted
D/MainActivity: main
總結
RxJava在剛剛接觸的時候使用起來會覺得比較別扭,主要是與java的方式存在一些差異,使用一段時間之后就會產生“RxJava太好用了”的感覺。一些原理性的東西這里介紹的比較簡單,大家有興趣的可以看一下給 Android 開發者的 RxJava 詳解,介紹的很詳細。