目录
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,完成。这里发射器用到了装饰模式。
再来张图总结一下