当前版本 2.2.19
RxJava2 (一)订阅流程源码阅读
RxJava2 (二)取消订阅流程 dispose( ) 源码阅读
RxJava2 (三)线程切换源码阅读
RxJava2 (四)切换UI主线程源码阅读
RxJava2 (五)just操作符源码阅读
RxJava2 (六)map操作符源码阅读
代码示例
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("Hello World");
emitter.onComplete();
}
})
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("onSubscribe");
// 取消订阅后,ObservableEmitter发出的消息,观察者Observer将不会再收到.
d.dispose();
}
@Override
public void onNext(String s) {
System.out.println("onNext: " + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
梳理对象
Observable
:抽象类,Observable.create(ObservableOnSubscribe<T> source)
最终创建一个ObservableCreate
对象返回.ObservableCreate
:Observable
的子类,实现了subscribeActual()
方法.它内部持有ObservableOnSubscribe
对象引用,ObservableOnSubscribe
:被观察者发射数据的是在ObservableOnSubscribe.subscribe()
方法中调用CreateEmitter
中的onNext()
,onComplete()
等方法.- 当执行
Observable.subscribe()
最终会调用ObservableCreate.subscribeActual()
,所有的数据发射由这里开始. CreateEmitter
:它在ObservableCreate.subscribeActual()
执行中被创建,它内部持有Observer引用.- 与取消订阅流程有关的点是,
CreateEmitter
实现了Disposable接口
综上:CreateEmitter对象,可以发射数据,可以取消订阅流程,它向上抽取了两个接口,一个接口专门封装了发射数据的方法,一个接口专门处理取消订阅的方法.
Observer.onSubscribe(Disposable d)
当调用Observable.subscribe()
最终会调用ObservableCreate.subscribeActual()
public final class ObservableCreate<T> extends Observable<T> {
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
// 观察者在这里调用了自身的onSubscribe()方法,传递过来的是CreateEmitter对象,不过onSubscribe(Disposable d)方法中的参数类型为Disposable.
observer.onSubscribe(parent);
...
}
}
// Disposable对象就是被当作参数传递到onSubscribe()方法中
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("onSubscribe");
// 取消订阅后,ObservableEmitter发出的消息,观察者Observer将不会再收到.
d.dispose();
}
@Override
public void onNext(String s) {
System.out.println("onNext: " + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
d.dispose();
取消订阅
dispose()
方法的具体实现需要去CreateEmitter
中看
// ObservableCreate.CreateEmitter类
public final class ObservableCreate<T> extends Observable<T> {
static final class CreateEmitter<T> extends AtomicReference<Disposable> implements ObservableEmitter<T>, Disposable {
// 取消订阅
@Override
public void dispose() {
// 这里的this就是CreateEmitter对象本身,看下DisposableHelper.dispose()
DisposableHelper.dispose(this);
}
// 判断是否取消订阅
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
}
// DisposableHelper类
public enum DisposableHelper implements Disposable {
DISPOSED
;
// field就是刚刚传递进来的CreateEmitter对象,CreateEmitter继承了AtomicReference<Disposable>.
// AtomicReference<Disposable>知识可以看这两个博客:
// https://www.jianshu.com/p/84c75074fa03
// https://blog.csdn.net/zxc123e/article/details/52057289
public static boolean dispose(AtomicReference<Disposable> field) {
// 获取AtomicReference<Disposable>对象中的值,不过CreateEmitter对象是直接new出来的,所以其中并没有值,此时current是为null.
Disposable current = field.get();
// DISPOSED是一个枚举
Disposable d = DISPOSED;
if (current != d) {
// 此时current为null,肯定与d不相等.
// getAndSet(d)意思是将field对象中的旧值设置为d,并且返回旧值,那么current肯定还是为null.
// 执行到这一步,AtomicReference<Disposable>对象中就存在一个枚举对象了.
current = field.getAndSet(d);
if (current != d) {
if (current != null) {
current.dispose();
}
return true;
}
}
return false;
}
// 判断传入的枚举类是否和当前枚举类相等.
// 如果相等,代表订阅已经取消了
// 如果不相等,代表订阅没有取消
public static boolean isDisposed(Disposable d) {
return d == DISPOSED;
}
}
emitter.onNext("Hello World")
发射数据,最终会调用到CreateEmitter
中的onNext(T t)
方法,这个过程会判断订阅是否取消.下面来看下.
public final class ObservableCreate<T> extends Observable<T> {
static final class CreateEmitter<T> extends AtomicReference<Disposable> implements ObservableEmitter<T>, Disposable {
@Override
public void onNext(T t) {
...
if (!isDisposed()) {
observer.onNext(t);
}
}
// 判断是否取消订阅
@Override
public boolean isDisposed() {
// 如果CreateEmitter对象调用了dispose()方法,最终会向CreateEmitter对象中存入一个枚举对象.
// CreateEmitter.get() 获取的就是这个枚举
// 上面有分析过
// 传入的枚举对象如果和枚举类中的枚举对象地址值相同,代表订阅已经取消了
// 如果地址值不相同,代表订阅没有取消
return DisposableHelper.isDisposed(get());
}
}
}
CompositeDisposable
简单说下CompositeDisposable
,它可以批量管理RxJava批量取消订阅操作.
CompositeDisposable mCompositeDisposable = new CompositeDisposable();
// 将所有的disposable对象都由mCompositeDisposable对象保管.
mCompositeDisposable.add(disposable);
下面看下CompositeDisposable
对象的add()
// CompositeDisposable类
public final class CompositeDisposable implements Disposable, DisposableContainer {
volatile boolean disposed; // 这个对象是用来标记当前的CompositeDisposable对象是否已经执行了取消订阅的操作
@Override
public boolean add(@NonNull Disposable disposable) {
ObjectHelper.requireNonNull(disposable, "disposable is null");
if (!disposed) { // 假如当前CompositeDisposable对象还未执行取消操作
synchronized (this) {
if (!disposed) {// 假如当前CompositeDisposable对象还未执行取消操作
OpenHashSet<Disposable> set = resources; // 创建Set集合
if (set == null) {
set = new OpenHashSet<Disposable>();
resources = set;
}
// 将disposable对象存入集合中
set.add(disposable);
return true;
}
}
}
// 假如当前的CompositeDisposable对象已经执行过了取消订阅的操作,那么就对传入的disposable进行取消操作
disposable.dispose();
return false;
}
// 对CompositeDisposable对象中set集合中的所有disposable进行取消订阅的操作
@Override
public void dispose() {
if (disposed) {
return;
}
OpenHashSet<Disposable> set;
synchronized (this) {
if (disposed) {
return;
}
disposed = true; // 将标记置为true,表示CompositeDisposable对象执行过了取消订阅的操作.
set = resources;
resources = null;
}
dispose(set);
}
void dispose(OpenHashSet<Disposable> set) {
if (set == null) {
return;
}
List<Throwable> errors = null;
Object[] array = set.keys();
for (Object o : array) {
if (o instanceof Disposable) {
try {
// 这里就是实际执行取消订阅的地方.
((Disposable) o).dispose();
}...
}
}
...
}
}
CompositeDisposable对象主要用来批量取消订阅,比如Activity中有多个RxJava订阅,我想在Activity销毁的时候统一对这些订阅进行取消,那么就可以先将Disposable对象都add到CompositeDisposable对象中,等到Activity执行onDestroy生命周期的时候调用CompositeDisposable对象的dispose(),进行统一取消订阅操作.