上一篇文章我们介绍,AndroidLifecycleScopeProvider提供了一个CompletableSource,这次我们看如何根据这个CompletableSource解订阅
public static <T> AutoDisposeConverter<T> autoDisposable(final CompletableSource scope) {
checkNotNull(scope, "scope == null");
return new AutoDisposeConverter<T>() {
@Override
public ParallelFlowableSubscribeProxy<T> apply(final ParallelFlowable<T> upstream) {
... }
@Override
public CompletableSubscribeProxy apply(final Completable upstream) {
...
}
@Override
public FlowableSubscribeProxy<T> apply(final Flowable<T> upstream) {
...
}
@Override
public MaybeSubscribeProxy<T> apply(final Maybe<T> upstream) {
...
}
@Override
public ObservableSubscribeProxy<T> apply(final Observable<T> upstream) {
...
}
@Override
public SingleSubscribeProxy<T> apply(final Single<T> upstream) {
...
}
};
}
创建一个AutoDisposeConverter
public interface AutoDisposeConverter<T>
extends FlowableConverter<T, FlowableSubscribeProxy<T>>,
ParallelFlowableConverter<T, ParallelFlowableSubscribeProxy<T>>,
ObservableConverter<T, ObservableSubscribeProxy<T>>,
MaybeConverter<T, MaybeSubscribeProxy<T>>,
SingleConverter<T, SingleSubscribeProxy<T>>,
CompletableConverter<CompletableSubscribeProxy> {}
可以看到,作者意图接管所有的Converter,然后通过一个代理类来处理自动解订阅的工作。这里我们挑一个经典的ObservableConverter 分析,通过上面的代码我们知道是这个函数的复写
@Override
public ObservableSubscribeProxy<T> apply(final Observable<T> upstream) {
...
}
把上游的upstream转化成一个ObservableSubscribeProxy,它是一个接口,我们看它的实现类
final class AutoDisposeObservable<T> extends Observable<T> implements ObservableSubscribeProxy<T> {
private final ObservableSource<T> source;
private final CompletableSource scope;
AutoDisposeObservable(ObservableSource<T> source, CompletableSource scope) {
this.source = source;
this.scope = scope;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
source.subscribe(new AutoDisposingObserverImpl<>(scope, observer));
}
}
没什么特别的,传递一个上游的ObservableSource,和处理生命周期的CompletableSource ,看它的subscribeActual订阅了一个AutoDisposingObserverImpl
final class AutoDisposingObserverImpl<T> extends AtomicInteger implements AutoDisposingObserver<T> {
@SuppressWarnings("WeakerAccess") // Package private for synthetic accessor saving
final AtomicReference<Disposable> mainDisposable = new AtomicReference<>();
@SuppressWarnings("WeakerAccess") // Package private for synthetic accessor saving
final AtomicReference<Disposable> scopeDisposable = new AtomicReference<>();
private final AtomicThrowable error = new AtomicThrowable();
private final CompletableSource scope;
private final Observer<? super T> delegate;
AutoDisposingObserverImpl(CompletableSource scope, Observer<? super T> delegate) {
this.scope = scope;
this.delegate = delegate;
}
@Override
public Observer<? super T> delegateObserver() {
return delegate;
}
@Override
public void onSubscribe(final Disposable d) {
DisposableCompletableObserver o =
new DisposableCompletableObserver() {
@Override
public void onError(Throwable e) {
scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposingObserverImpl.this.onError(e);
}
@Override
public void onComplete() {
scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(mainDisposable);
}
};
if (AutoDisposeEndConsumerHelper.setOnce(scopeDisposable, o, getClass())) {
delegate.onSubscribe(this);
scope.subscribe(o);
AutoDisposeEndConsumerHelper.setOnce(mainDisposable, d, getClass());
}
}
@Override
public boolean isDisposed() {
return mainDisposable.get() == AutoDisposableHelper.DISPOSED;
}
@Override
public void dispose() {
AutoDisposableHelper.dispose(scopeDisposable);
AutoDisposableHelper.dispose(mainDisposable);
}
@Override
public void onNext(T value) {
if (!isDisposed()) {
if (HalfSerializer.onNext(delegate, value, this, error)) {
// Terminal event occurred and was forwarded to the delegate, so clean up here
mainDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(scopeDisposable);
}
}
}
@Override
public void onError(Throwable e) {
if (!isDisposed()) {
mainDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(scopeDisposable);
HalfSerializer.onError(delegate, e, this, error);
}
}
@Override
public void onComplete() {
if (!isDisposed()) {
mainDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(scopeDisposable);
HalfSerializer.onComplete(delegate, this, error);
}
}
}
构造方法不说了看它的onSubscribe,new 了一个DisposableCompletableObserver ,scope去订阅,这段代码说明我们的生命周期被订阅了,当生命周期结束的时候执行DisposableCompletableObserver的onComplete方法,我们看到
@Override
public void onComplete() {
scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(mainDisposable);
}
scopeDisposable被dispose了,mainDisposable被解订阅了,这个mainDisposable是个Dispose的原子类型的引用,我们可以看到它用来标记我们当前的这个Observable是否已经被解订阅。如果解订阅了,就不会再发送数据了。
最后想一个问题
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Thread.sleep(3000);
emitter.onNext(1);
}
})
.subscribeOn(SchedulerProvider.db())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(3);
}
})
.observeOn(AndroidSchedulers.mainThread())
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(ViewClick.this, Lifecycle.Event.ON_DESTROY))
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
像这种嵌套的Rxjava,外部没有生命周期订阅的处理,内部嵌套一个Rxjava observable的处理,添加了自动解订阅。在Activity生命周期结束后,嵌套的内部Rxjava是否会继续执行完毕?
答案是会继续执行完,也就是说内部Rxjava的
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(ViewClick.this, Lifecycle.Event.ON_DESTROY))
没有效果。原因就是如果activity生命周期结束,外部的Rxjava依然在执行,当执行到accept方法时,内部订阅虽然用了as操作符号,但是我们通过源码知道生命周期被包装成了一个completeableSource,而它在转换前并不是一个BehaviorSubject,而只是一个冷的observable,普通的Observable,它订阅了之后,生命周期已经结束,Lifecycle并不会发送任何数据,也就是completeableSource不会收到complete事件,所以也就起不了作用。
最后文章有不清晰的地方,欢迎指出。