Rxjava中使用AutoDispose(版本1.4.0)解決內存泄漏的原理分析
原文
問題:AutoDispose主要是通過監聽view的生命週期來解決使用Rxjava時的內存泄漏的,那麼view的生命週期和Rxjava的鏈式調用是如何關聯的?
在Activity中使用非常簡單,入口如下:
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
}
//分析點1,入口
}).as(AutoDispose.<String>autoDisposable(AndroidLifecycleScopeProvider.from(this)))
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
});
分析點1:autoDisposable中傳入的是ScopeProvider ,首先看一下AndroidLifecycleScopeProvider.from(this))是如何生成ScopeProvider
//分析點1,入口
as(AutoDispose.<String>autoDisposable(AndroidLifecycleScopeProvider.from(this)))
//分析點2
public static <T> AutoDisposeConverter<T> autoDisposable(final ScopeProvider provider) {
checkNotNull(provider, "provider == null");
//分析點3,分析比較靠後
return autoDisposable(completableOf(provider));
}
分析點2:AndroidLifecycleScopeProvider.from(this))的流程分析
public static AndroidLifecycleScopeProvider from(LifecycleOwner owner) {
//獲取對應的lifecycle
return from(owner.getLifecycle());
}
public static AndroidLifecycleScopeProvider from(Lifecycle lifecycle) {
//使用默認的生命週期對應關係
return from(lifecycle, DEFAULT_CORRESPONDING_EVENTS);
}
public static AndroidLifecycleScopeProvider from(
Lifecycle lifecycle, CorrespondingEventsFunction<Lifecycle.Event> boundaryResolver) {
//分析點4 封裝lifecycle和boundaryResolver
return new AndroidLifecycleScopeProvider(lifecycle, boundaryResolver);
}
//這裏是訂閱和取消訂閱對應的生命週期,比如在onCreate中訂閱,那麼在onDestroy中取消訂閱
//重點啊,後邊要用到,這裏省略的方法是apply()
private static final CorrespondingEventsFunction<Lifecycle.Event> DEFAULT_CORRESPONDING_EVENTS =
lastEvent -> {
switch (lastEvent) {
case ON_CREATE:
return Lifecycle.Event.ON_DESTROY;
case ON_START:
return Lifecycle.Event.ON_STOP;
case ON_RESUME:
return Lifecycle.Event.ON_PAUSE;
case ON_PAUSE:
return Lifecycle.Event.ON_STOP;
case ON_STOP:
case ON_DESTROY:
default:
throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent);
}
};
分析點4:AndroidLifecycleScopeProvider封裝lifecycle和boundaryResolver
private AndroidLifecycleScopeProvider(
Lifecycle lifecycle, CorrespondingEventsFunction<Lifecycle.Event> boundaryResolver) {
//分析點5:將lifecycle封裝爲LifecycleEventsObservable
this.lifecycleObservable = new LifecycleEventsObservable(lifecycle);
this.boundaryResolver = boundaryResolver;
}
@Override
//重點啊,後邊要用到 ,返回封裝的被觀察者對象lifecycleObservable
public Observable<Lifecycle.Event> lifecycle() {
return lifecycleObservable;
}
@Override
//重點啊,後邊要用到,返回分析點2中提到的DEFAULT_CORRESPONDING_EVENTS
public CorrespondingEventsFunction<Lifecycle.Event> correspondingEvents() {
return boundaryResolver;
}
@Override
//重點啊,後邊要用到 返回當前的生命週期
public Lifecycle.Event peekLifecycle() {
lifecycleObservable.backfillEvents();
return lifecycleObservable.getValue();
}
@Override
//重點啊,後邊要用到
public CompletableSource requestScope() {
// 分析點6 :創建CompletableSource
return LifecycleScopes.resolveScopeFromLifecycle(this);
}
分析點5:將lifecycle封裝爲LifecycleEventsObservable,LifecycleEventsObservable在被訂閱時,實現對view生命週期的綁定
class LifecycleEventsObservable extends Observable<Event> {
private final Lifecycle lifecycle;
private final BehaviorSubject<Event> eventsObservable = BehaviorSubject.create();
@SuppressWarnings("CheckReturnValue")
LifecycleEventsObservable(Lifecycle lifecycle) {
//帶參的構造函數
this.lifecycle = lifecycle;
}
//返回生命週期
Event getValue() {
return eventsObservable.getValue();
}
/**
* Backfill if already created for boundary checking. We do a trick here for corresponding events
* where we pretend something is created upon initialized state so that it assumes the
* corresponding event is DESTROY.
*/
void backfillEvents() {
@Nullable Lifecycle.Event correspondingEvent;
switch (lifecycle.getCurrentState()) {
case INITIALIZED:
correspondingEvent = ON_CREATE;
break;
case CREATED:
correspondingEvent = ON_START;
break;
case STARTED:
case RESUMED:
correspondingEvent = ON_RESUME;
break;
case DESTROYED:
default:
correspondingEvent = ON_DESTROY;
break;
}
eventsObservable.onNext(correspondingEvent);
}
@Override
//重點啊,後邊要用到
//在被訂閱時,實現對view生命週期的綁定
protected void subscribeActual(Observer<? super Event> observer) {
//創建一個生命週期觀察者archObserver
ArchLifecycleObserver archObserver =
new ArchLifecycleObserver(lifecycle, observer, eventsObservable);
observer.onSubscribe(archObserver);
if (!isMainThread()) {
observer.onError(
new IllegalStateException("Lifecycles can only be bound to on the main thread!"));
return;
}
//添加View生命週期的觀察者
lifecycle.addObserver(archObserver);
if (archObserver.isDisposed()) {
lifecycle.removeObserver(archObserver);
}
}
//View生命週期的觀察者
static final class ArchLifecycleObserver extends MainThreadDisposable
implements LifecycleObserver {
private final Lifecycle lifecycle;
private final Observer<? super Event> observer;
private final BehaviorSubject<Event> eventsObservable;
ArchLifecycleObserver(
Lifecycle lifecycle,
Observer<? super Event> observer,
BehaviorSubject<Event> eventsObservable) {
this.lifecycle = lifecycle;
this.observer = observer;
this.eventsObservable = eventsObservable;
}
@Override
protected void onDispose() {
lifecycle.removeObserver(this);
}
@OnLifecycleEvent(Event.ON_ANY)
void onStateChange(@SuppressWarnings("unused") LifecycleOwner owner, Event event) {
if (!isDisposed()) {
if (!(event == ON_CREATE && eventsObservable.getValue() == event)) {
// Due to the INITIALIZED->ON_CREATE mapping trick we do in backfill(),
// we fire this conditionally to avoid duplicate CREATE events.
eventsObservable.onNext(event);
}
//重點啊,後邊要用到
//view生命週期變化時,調用 LifecycleEventsObservable.onNext,觀察者在分析點8中
observer.onNext(event);
}
}
}
}
分析點6:resolveScopeFromLifecycle()傳入的是分析點4創建的AndroidLifecycleScopeProvider
@Override
public CompletableSource requestScope() {
//分析點6:
return LifecycleScopes.resolveScopeFromLifecycle(this);
}
//provider爲AndroidLifecycleScopeProvider
public static <E> CompletableSource resolveScopeFromLifecycle(
final LifecycleScopeProvider<E> provider, final boolean checkEndBoundary)
throws OutsideScopeException {
//獲取生命週期
E lastEvent = provider.peekLifecycle();
CorrespondingEventsFunction<E> eventsFunction = provider.correspondingEvents();
if (lastEvent == null) {
throw new LifecycleNotStartedException();
}
E endEvent;
try {
//eventsFunction爲DEFAULT_CORRESPONDING_EVENTS 參考分析點2和4
//獲取取消訂閱的生命週期
endEvent = eventsFunction.apply(lastEvent);
} catch (Exception e) {
。。。。。。。
}
//傳入LifecycleEventsObservable(參考分析點4)和取消訂閱的生命週期
return resolveScopeFromLifecycle(provider.lifecycle(), endEvent);
}
//最終執行到這裏,參數依次爲LifecycleEventsObservable,endEvent和比較器
public static <E> CompletableSource resolveScopeFromLifecycle(
Observable<E> lifecycle, final E endEvent, @Nullable final Comparator<E> comparator) {
Predicate<E> equalityPredicate;
if (comparator != null) {
equalityPredicate = e -> comparator.compare(e, endEvent) >= 0;
} else {
equalityPredicate = e -> e.equals(endEvent);
}
//重點啊,後邊要用到
//注意這裏只返回了CompletableSource,並沒有添加觀察者進行訂閱,在分析點8中添加的
//創建CompletableSource ,在滿足取消訂閱的條件時執行ignoreElements,
//ignoreElements只會執行onComplete和onError
return lifecycle.skip(1).takeUntil(equalityPredicate).ignoreElements();
}
}
分析點3:provider爲AndroidLifecycleScopeProvider(參考分析點2)
//分析點3,分析比較靠後
return autoDisposable(completableOf(provider));
public static Completable completableOf(ScopeProvider scopeProvider) {
return Completable.defer(
() -> {
try {
//返回的是分析點6中生成的 CompletableSource
return scopeProvider.requestScope();
} catch (OutsideScopeException e) {
。。。。。。。。。
});
}
//傳入分析點6中生成的 CompletableSource
public static <T> AutoDisposeConverter<T> autoDisposable(final CompletableSource scope) {
checkNotNull(scope, "scope == null");
return new AutoDisposeConverter<T>() {
。。。。。。。。。。。。。。
@Override
//Rxjava的as()操作符中調用AutoDisposeConverter的apply(),返回一個ObservableSubscribeProxy對象
public ObservableSubscribeProxy<T> apply(final Observable<T> upstream) {
if (!AutoDisposePlugins.hideProxies) {
return new AutoDisposeObservable<>(upstream, scope);
}
return new ObservableSubscribeProxy<T>() {
。。。。。。。。。。。。
@Override
public Disposable subscribe(
Consumer<? super T> onNext, Consumer<? super Throwable> onError) {
//當ObservableSubscribeProxy被訂閱時,生成封裝的AutoDisposeObservable(上游的Observable,分析點6中生成的 CompletableSource )
//分析點7
return new AutoDisposeObservable<>(upstream, scope).subscribe(onNext, onError);
}
。。。。。。。。。。。。。
}
。。。。。。。。。。。。。。。。。。。
}
分析點7:生成封裝的AutoDisposeObservable(上游的Observable,分析點6中生成的 CompletableSource ),並執行subscribe,實際上就是執行了AutoDisposeObservable的subscribeActual()
//分析點7
return new AutoDisposeObservable<>(upstream, scope).subscribe(onNext, onError);
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) {
//上游的Observable
this.source = source;
//分析點6中生成的 CompletableSource
this.scope = scope;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
//分析點8:上游的Observable被封裝的AutoDisposingObserverImpl()的觀察者訂閱
source.subscribe(new AutoDisposingObserverImpl<>(scope, observer));
}
}
分析點8:上面分析了那麼多,這裏纔是真正的實現的地方。
上游的Observable被封裝的AutoDisposingObserverImpl()的觀察者訂閱,重點在onSubscribe()的回調處理
final class AutoDisposingObserverImpl<T> extends AtomicInteger implements AutoDisposingObserver<T> {
。。。。。。。。。。。。。。。。。
AutoDisposingObserverImpl(CompletableSource scope, Observer<? super T> delegate) {
//分析點6中生成的 CompletableSource
this.scope = scope;
//原有的觀察者
this.delegate = delegate;
}
@Override
public Observer<? super T> delegateObserver() {
return delegate;
}
@Override
public void onSubscribe(final Disposable d) {
//創建一個DisposableCompletableObserver ,只有onError和onComplete回調
//這個是和分析點6中提到的ignoreElements()是對應的
DisposableCompletableObserver o =
new DisposableCompletableObserver() {
@Override
//設置鏈式調用爲Dispose
public void onError(Throwable e) {
scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposingObserverImpl.this.onError(e);
}
@Override
//設置鏈式調用爲Dispose
public void onComplete() {
scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(mainDisposable);
}
};
if (AutoDisposeEndConsumerHelper.setOnce(scopeDisposable, o, getClass())) {
delegate.onSubscribe(this);
//分析點6中生成的 CompletableSource是沒有添加觀察者的
//反向訂閱,最終回調到分析點5中LifecycleEventsObservable的subscribeActual()實現對view生命週期的綁定
//當生命週期發生變化時,會調用LifecycleEventsObservable.onNext(生命週期),
//這行代碼翻譯過來,實際上就是LifecycleEventsObservable.skip(1).takeUntil("是取消訂閱的生命週期").ignoreElements().subscribe(DisposableCompletableObserver )
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);
}
}
}
總結:現在回答上文的問題
AutoDispose主要是通過監聽view的生命週期來解決使用Rxjava時的內存泄漏的,那麼view的生命週期和Rxjava的鏈式調用是如何關聯的?
1:AndroidLifecycleScopeProvider.from(this))中獲取當前view的lifecycle,並創建一個LifecycleEventsObservable(參考分析點5),在其subscribeActual中實現了對View生命週期的訂閱。
當生命週期發生變化時,會執行LifecycleEventsObservable.onNext(“生命週期”).
2:在Rxjava的as操作符中AutoDisposeConverter.apply()中生成了觀察者的代理實現類AutoDisposingObserverImpl(參考分析點8),並在onSubscribe中實現了觀察者的訂閱,經過翻譯代碼如下
LifecycleEventsObservable.skip(1).takeUntil("取消訂閱生命週期").ignoreElements()
.subscribe(DisposableCompletableObserver )