RxJava2原理流程分析1- Observable观察订阅的的简单分析

概述:

从最简单的RxJava的使用,来分析RxJava订阅和观察的整个流程(注:RxJava版本:2.2.7)

目标:

1.RxJava中观察者和被观察者是如何联系起来的
2.被观察者(Observable)发射数据是从什么时候开始的,
3. Observable的整个流程图

分析

最简单的RxJava代码如下:下面代码实现了 被观察者,发射一个1,观察者得到该发射的值并打印出来

Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext(1);
emitter.onComplete();
}
}).subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d(“RxJava:”, “onSubscribe”);
}

            @Override
            public void onNext(Object o) {
                Log.d("RxJava:", "onNext"+o.toString());
            }

            @Override
            public void onError(Throwable e) {
                Log.d("RxJava:", "onError");
            }

            @Override
            public void onComplete() {
                Log.d("RxJava:", "onComplete");
            }
        });

运行结果:
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onSubscribe
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onNext1
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onComplete

我们首先查看 Observable.create()方法,如下:

public static Observable create(ObservableOnSubscribe source) {
//判断是否为空,如果为null 则抛出异常
ObjectHelper.requireNonNull(source, “source is null”);
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}

RxJavaPlugins.onAssembly() 方法
/**

  • Calls the associated hook function. 调用关联的hook方法
  • @param the value type
  • @param source the hook’s input value hook的输入值
  • @return the value returned by the hook hook的返回值
    */
    @NonNull
    public static Observable onAssembly(@NonNull Observable source) {
    Function<? super Observable, ? extends Observable> f = onObservableAssembly;
    if (f != null) {
    return apply(f, source);
    }
    return source;
    }
    该函数是个hook函数 ,当设置hook函数的时候,会执行hook函数,默认情况下是没有设置的,即是onObservableAssembly=null,此处我们可以忽略.所以
    public static Observable create(ObservableOnSubscribe source) 实际上返回的是new ObservableCreate(source)
    整个函数流程即是

new ObservableCreate(source).subscribe(new Observer() {…}

ObservableCreate类:
//继承Observable
public final class ObservableCreate extends Observable {
final ObservableOnSubscribe source;

public ObservableCreate(ObservableOnSubscribe source) {
//缓存 ObservableOnSubscribe 这个是我们声明的
//new ObservableOnSubscribe() {
// @Override
// public void subscribe(ObservableEmitter emitter) throws Exception {
// emitter.onNext(1);
// emitter.onComplete();
// }
//}
this.source = source;
}
//实现Observable的抽象函数 这个是重点
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);

try {
    source.subscribe(parent);
} catch (Throwable ex) {
    Exceptions.throwIfFatal(ex);
    parent.onError(ex);
}

}

}

我们现在知道了 ObservableCreate是Observable的一个实现类,接下来继续走流程即是 .subscribe(new Observer(){}),这个方法点进去是Observable的一个方法,

public abstract class Observable implements ObservableSource {

@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
//observer的非空判断
ObjectHelper.requireNonNull(observer, “observer is null”);
try {
//这个是和RxJavaPlugins.onAssembly()一样的hook方法 默认不走
observer = RxJavaPlugins.onSubscribe(this, observer);
//判断hook后的observer是否非空
ObjectHelper.requireNonNull(observer, “The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins”);
//实际上调用的方法
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;
}

}

//抽象方法
protected abstract void subscribeActual(Observer<? super T> observer);

}

我们前面在ObservableCreate类中,看到了其实现的subscribeActual方法

//实现Observable的抽象函数 这个是重点
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
//1
observer.onSubscribe(parent);
try {
//2
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
//3
parent.onError(ex);
}
}

上述1处:调用observer的onSubscribe方法
@Override
public void onSubscribe(Disposable d) {
Log.d(“RxJava:”, “onSubscribe”);
}
上述2处:source.subscribe(parent);
在ObservableCreate类中我们看到 source是其保存的ObservableOnSubscribe实例,即是我们在代码中实现的那个,调用.subscribe(parent)即是:

 @Override
    public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
        emitter.onNext(1);
        emitter.onComplete();
    }

上述3处 当初source.subscribe的过程中出现异常便会调用 CreateEmitter的onError的方法 最后调用Observer的onNext方法

我们现在知道了 Observable.create(ObservableOnSubscribe).subscribe(Observer)
实际上是: ObservableOnSubscribe.subscribe(new CreateEmitter(Observer)) ,ObservableOnSubscribe是我们前面实现的 类 ,
我们在其subscribe方法中进行,使用CreateEmitter发射数据 并最终调用complete()方法
接下来我们看下CreateEmitter

CreateEmitter类

static final class CreateEmitter<T>

extends AtomicReference
implements ObservableEmitter, Disposable {

private static final long serialVersionUID = -3434801548987643227L;

final Observer<? super T> observer;

CreateEmitter(Observer<? super T> observer) {
	//缓存我们设置的观察者 Observer
    this.observer = observer;
}
//该方法是我们在ObservableOnSubscribe的subscribe方法中调用的emitter.onNext(1);
@Override
public void onNext(T t) {
	//先判断发射在数据是否为null 
    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的方法,即是最后我们回调的方法
        observer.onNext(t);
    }
}
//在上述3中调用的onError方法 最终调用Observer的onError方法
@Override
public void onError(Throwable t) {
    if (!tryOnError(t)) {
		//设置hook方法 忽略
        RxJavaPlugins.onError(t);
    }
}

@Override
public boolean tryOnError(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方法
            observer.onError(t);
        } finally {
            dispose();
        }
        return true;
    }
    return false;
}
//同上原理 先判断是否取消订阅
@Override
public void onComplete() {
    if (!isDisposed()) {
        try {
            observer.onComplete();
        } finally {
            dispose();
        }
    }
}
//存储Disposable类 用来判断是否取消了订阅
@Override
public void setDisposable(Disposable d) {
    DisposableHelper.set(this, d);
}

@Override
public void setCancellable(Cancellable c) {
    setDisposable(new CancellableDisposable(c));
}

@Override
public ObservableEmitter<T> serialize() {
    return new SerializedEmitter<T>(this);
}
//取消订阅
@Override
public void dispose() {
    DisposableHelper.dispose(this);
}
//判断是否取消了订阅
@Override
public boolean isDisposed() {
    return DisposableHelper.isDisposed(get());
}

@Override
public String toString() {
    return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
}

}

上述例子的整体流程如下:
1.生成ObservableOnSubscribe实例 实现其subscribe(ObservableEmitter emitter)方法,使用emitter发射数据
2.生成ObservableCreate实例,该类实现了Observable
3.Observer订阅Observable 调用ObservableCreate的subscribeActual(observer)
4.生成ObservableEmitter的实例CreateEmitter对象,调用Observer的onSubscribe的方法,
5.调用ObservableOnSubscribe的subscribe方法:即是我们上面实现的发射数据的方法

现在回答上面的两个问题:

(1)RxJava中观察者和被观察者在ObservableCreate实例中是通过CreateEmitter类关联起来的
(2)被观察者(Observable)发射数据是在订阅后开始发射数据的 即是ObservableOnSubscribe调用subscribe方法
(3)Observable的整个流程图如上面分析

为了更直观的分析其整个结构 下面画出其UML类图,

在这里插入图片描述

上面分析以及UML类图中都指到了Disposable这个接口,该接口主要是实现判断是否取消订阅,如果取消订阅则不再执行想要的回调,我们在CreateEmitter类中也看到了相关的代码,

public interface Disposable {
/**
 * Dispose the resource, the operation should be idempotent.
 * 取消订阅
 */
void dispose();

/**
 * Returns true if this resource has been disposed.
 * @return true if this resource has been disposed
 * 是否取消订阅
 */
boolean isDisposed();

}

在不同的Observable内的实现方式不同,这里不在详细说明
欢迎志同道合的朋友留下评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值