“码上理解”--- 手撕RxJava订阅关系,事件发送和接收

21 篇文章 1 订阅
5 篇文章 0 订阅

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值