目錄
RxJava簡單介紹
RxJava現在幾乎每個Android項目中都有它的身影,RxJava是使用了Rx(ReactiveX)函數庫的語言庫,Rx是一個函數庫,讓開發者可以利用可觀察序列和LINQ風格查詢操作符來編寫異步和基於事件的程序,除了RxJava,Rx幾乎支持了全部的流行編程語言,例如:RxJS、Rx.NET等等。
文章目的
通過一個栗子(創建操作符由很多,這裏以create操作符爲例),再結合源碼來理清RxJava 訂閱關係是如何實現的,以及舉例onNext事件發送和接收,粒度上本文關注流程實現相關代碼,無關於流程的代碼不關注。
環境搭建和代碼示例
配置和代碼很簡單,如下
implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
public class MainActivity extends AppCompatActivity {
private Disposable disposable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rxJava1();
}
public void rxJava1(){
//創建操作符采用create
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("事件1");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.i("RxJava","訂閱完成了");
disposable = d;
}
@Override
public void onNext(String s) {
Log.i("RxJava",s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (disposable != null)
if (!disposable.isDisposed())
disposable.dispose();
}
}
運行結果
24075-24075/com.himi.rxjavaanalysis I/RxJava: 訂閱完成了
24075-24075/com.himi.rxjavaanalysis I/RxJava: 事件1
既然研究訂閱關係,那麼我從subscribe方法入手
subscribe()方法
由上面的例子所示,subscribe方法傳入了Observer對象(相當於觀察者),來點擊subscribe方法卡看源碼是怎麼實現的
public abstract class Observable<T> implements ObservableSource<T> {
...
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
//重點是這句代碼,其它代碼是一些健壯性判斷或者添加hook等
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
...
}
我們看到subscribe方法是抽象類Observable中的方法,方法中以observer爲參數調用了subscribeActual(observer)方法,繼續查看subscribeActual方法的源碼
public abstract class Observable<T> implements ObservableSource<T>{
...
protected abstract void subscribeActual(Observer<? super T> observer);
...
}
發現subscribeActual方法是抽象類Observable的抽象方法,那哪裏實現了這個方法呢?
我們知道subscribe方法是Observable.create(new ObservableOnSubscribe< String>() {…})調用的,推測Observable.create(new ObservableOnSubscribe< String>() {})實現了Observable抽象方法,並實現了subscribeActual方法。那來看一下Observable.create(new ObservableOnSubscribe< String>() {…})具體做了什麼
Observable.create(new ObservableOnSubscribe< String>() {})
查看create()源碼
public abstract class Observable<T> implements ObservableSource<T>{
...
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
// hook
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
...
}
發現返回了一個Observable對象 RxJavaPlugins.onAssembly(new ObservableCreate(source)),參數是傳入的ObservableOnSubscribe對象,究竟這個方法將ObservableOnSubscribe怎麼樣了呢,繼續看RxJavaPlugins.onAssembly()的實現方式
/**
* Calls the associated hook function.
* @param <T> the value type
* @param source the hook's input value
* @return the value returned by the hook
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
由註釋可以瞭解,這個方法跟hook有關係,繼續看方法內部
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
方法中判斷了如果f爲null 就返回參數,如果f不爲null,就返回apply方法的返回值,那onObservableAssembly在哪賦值的呢?
發現RxJavaPlugins的840行給其賦值了,我們順勢看一下
由註釋可以瞭解,這是設置hook的方法,發現是這個方法給onObservableAssembly賦值了,我們點擊setOnObservableAssembly方法查看哪裏由調用onObservableAssembly,發現程序中除了初始化的地方調用了setOnObservableAssembly(null),給onObservableAssembly賦值了null,其餘地方沒用到,所以,可以知道onAssembly的返回值就是傳入的ObservableCreate對象,也就是Observable.create()方法最終返回的是ObservableCreate對象。
此時我們可以推測一下,ObservableCreate肯定是Observable的實現類,也實現了subscribeActual方法,看一下源碼是否如此:
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
// 實現了subscribeActual
@Override
protected void subscribeActual(Observer<? super T> observer) {
//將觀察者observer包裝一下,放入發射器中
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//調用observer的onSubscribe方法,表示訂閱完成,
//參數是CreateEmitter對象,CreateEmitter實現了Disposable接口,onSubscribe中可以拿到Disposable對象調用dispose
observer.onSubscribe(parent);
try {
//拿到ObservableOnSubscribe對象,回調subscribe方法,並將發射器帶過去,方便對事件發送
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);
} finally {
dispose();
}
} else {
RxJavaPlugins.onError(t);
}
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
... ...
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
}
不出意外,確實如推測的那樣,ObservableCreate類實現了subscribeActual抽象方法,也就是當執行subscribe訂閱方法的時候,是調用了ObservableCreate類的subscribeActual方法。其方法內幹了3件事情:
1.以observer爲參數創建了一個發射器
2.調用了observer的onSubscribe方法
3.調用了source的subscribe方法,並將發射器傳遞過去
我們先看第一件事
1.以observer爲參數創建了一個發射器
根據源碼我們可以知道,發射器中包含observer對象,也有與observer相對應的onNext、onError、onComplete回調方法,在發射器的回調方法中,執行了對應observer的回調方法,比方e.onNext中執行了observer.onNext
2.調用observer的onSubscribe方法
當RxJava配合retorfit+okhttp來請求網絡,如果請求網絡時需要加進度圈,我們通常在項目要在observer的onSubscribe方法中添加,原因是
1.onSubscribe方法一般執行在主線程(除非整個Rxjava代碼都寫在子線程,onSubscribe也會在子線程)
2.訂閱關係一旦生成,就回回調onSubscribe方法
3.調用source的subscribe方法,並將發射器傳遞過去
還記得source是怎麼來的嗎,是通過ObservableCreate的構造函數傳遞進來的
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
由前面的推理可以知道,source就是Observable.create()方法的參數
new ObservableOnSubscribe< String>() {
@Override
public void subscribe(ObservableEmitter< String> e) throws Exception {
e.onNext("事件1");
}
}
那source.subscribe(parent);就是回調了subscribe方法,拿到發射器然後調用發射器emitter的onNext方法發射“事件1”,由於發射器Emitter的onNext方法中調用了觀察者observer的onNext方法,所以事件直接回調到observer的onNext方法,完成事件的發送和監聽
總結(以create操作符爲例)
RxJava訂閱關係在ObservableCreate類中實現。先將被觀察者包裝成一個發射器,這時候就算訂閱完成了,執行observer.onSubscribe方法,然後調用source.subscribe方法,被觀察者拿到發射器發送事件,其實就是先調用e.onNext先揭開包裹,拿到觀察者observer,然後調用observer.onNext,完成。這裏發射器用到了裝飾模式。
再來張圖總結一下