版權聲明:本文爲博主原創文章,未經博主允許不得轉載https://blog.csdn.net/wsygyb/article/details/90523082
目錄
概述
最近的項目採用AutoDispose解決RxJava內存泄漏的問題.相對於讓組件繼承RxActivity或者RxFragment,使用AutoDispose只需要簡單地加上.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
,就能非常漂亮並且保持較少侵入性的解決內存泄漏問題.當然本篇文章的重點不在於講述AutoDispose如何使用,而是闡述AutoDispose如何通過監聽Lifecycle來實現dispose.
必備的知識體系
在講述原理之前,需要確保具有以下知識點的儲備:
- Lifecycle ,通過實現LifecycleObserver的方式訂閱Lifecycle的事件,訂閱者不會強引用lifecycle本身;
- RxJava2,瞭解Observable的鏈式引用原理.以及map、filter等操作符;
Lifecycle監聽生命週期
通過@OnLifecycleEvent註解可以訂閱Lifecycle的特定事件,同時訂閱者不會強引用Lifecycle本身,從源碼來看:比如SupportActivity,在調用getLifecycle時返回的是LifecycleRegistry
,裏面維持的是對Activity本身的弱引用.
public class MyObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
}
}
aLifecycleOwner.getLifecycle().addObserver(new MyObserver());
RxJava的內存泄漏場景
當RxJava在異步線程中執行耗時任務(比如網絡請求、IO等),在該任務未結束前由於持有Activity的Context將導致Activity無法被正常銷燬。從代碼來看,Observable.create創建了一個ObservableCreate
(繼承自Observable),該Observable在被訂閱時會創建CreateEmitter來保存observer的實例.由於該實例引用Context,將使得Activity無法被回收.
Observable.create<String>{
observer ->
observer.onNext("")
observer.onComplete()
}
.observeOn(Schedulers.io())
.subscribe{
t->
val context=this@DActivity
Thread.sleep(5000)
Log.d("",context.toString())
}
AutoDispose在Activity::onDestroy時避免內存泄漏
- AutoDispose在內部創建了
ArchLifecycleObserver
,採用Event.ON_ANY註解監聽Lifecyc的生命週期 - 當Lifecycle發出ON_DESTROY事件時,ArchLifecycleObserver轉發該事件給特定observer,該observer通過filter限定Event.ON_DESTROY事件通過
- 隨後當Activity銷燬時,Lifecycle發送事件給``ArchLifecycleObserver··,並調用onDispose方法取消對Lifecycle的監聽。最後回調至ObservableCreate在訂閱時創建的CreateEmitter的dispose方法,將CreateEmitter本身賦值爲DISPOSED,銷燬observer實例.
AutoDispose的創建
首先,AutoDispose會獲取當前Context的lifecycle,並對應地創建一個observer用於監聽lifecycle的變化。隨後會 例如下面產生的一個序列圖:
首先,AutoDispose會調用當前LifecycleOwner的getLifecycle,實現如下所示:
public static AndroidLifecycleScopeProvider from(LifecycleOwner owner) {
return from(owner.getLifecycle());
}
在本文中,LifecycleOwner的實例是Activity,故調用getLifecycle返回的是LifecycleRegistry.隨後調用from(lifecycle, DEFAULT_CORRESPONDING_EVENTS)
創建AndroidLifecycleScopeProvider,如下所示:
public static AndroidLifecycleScopeProvider from(
Lifecycle lifecycle,
Function<Lifecycle.Event, Lifecycle.Event> boundaryResolver) {
return new AndroidLifecycleScopeProvider(lifecycle, boundaryResolver);
}
DEFAULT_CORRESPONDING_EVENTS
是AndroidLifecycleScopeProvider內部創建的一個Function,該Function的作用用於返回對應初始生命週期的結束生命週期,聲明如下所示:
private static final Function<Lifecycle.Event, Lifecycle.Event> DEFAULT_CORRESPONDING_EVENTS =
new Function<Lifecycle.Event, Lifecycle.Event>() {
@Override public Lifecycle.Event apply(Lifecycle.Event lastEvent) throws Exception {
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:
...
}}};
隨後,AndroidLifecycleScopeProvider內部根據傳入的lifecycle創建了一個observer,用於監聽本文中Activity的生命週期,並對應地創建一個Observable用於監聽lifecycle的變化,實現如下:
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 protected void subscribeActual(Observer<? super Event> observer) {
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;
}
lifecycle.addObserver(archObserver);
if (archObserver.isDisposed()) {
lifecycle.removeObserver(archObserver);
}
}
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(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);
}
observer.onNext(event);
}
}
}
}
AutoDispose被訂閱
本文中的示例代碼如下:
Observable.create<String> {
observer ->
observer.onNext("first")
observer.onNext("second")
}
.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
.subscribe {
it->
val context=this@MainActivity
Log.d("",context.toString())
}
as操作符以及AutoDispose的訂閱流程如下所示:
首先,Observable::create會創建一個ObservableCreate對象,而AutoDispose.autoDisposable
會創建AutoDisposeConverter對象.as
操作符調用前面生成的AutoDisposeConverter的apply方法,由於這裏傳入的是Observable對象,故執行下列方法調用:
public ObservableSubscribeProxy<T> apply(Observable<T> upstream) {
//這裏的scope對應的是之前調用deferredResolvedLifecycle返回的Maybe對象
return (ObservableSubscribeProxy)upstream.to(new ObservableScoper(scope));
}
Observable::to調用ObservableScoper的apply(observable)方法創建一個ObservableSubscribeProxy對象,聲明如下:
public ObservableSubscribeProxy<T> apply(final Observable<? extends T> observableSource)
throws Exception {
return new ObservableSubscribeProxy<T>() {
@Override public Disposable subscribe() {
return new AutoDisposeObservable<>(observableSource, scope()).subscribe();
}
@Override public Disposable subscribe(Consumer<? super T> onNext) {
//observableSource -> 示例中通過Observable::create創建的ObservableCreate對象
//scope() -> 調用deferredResolvedLifecycle生成的Maybe<LifecycleEndNotification>
return new AutoDisposeObservable<>(observableSource, scope()).subscribe(onNext);
}
}
}
待ObservableSubscribeProxy創建完成後,as
操作符調用完成。接着正式進入訂閱流程。通過Consumer訂閱,執行AutoDisposeObservable的subscribeActual方法,如下:
@Override protected void subscribeActual(Observer<? super T> observer) {
//source -> 實例中創建的ObservablCreate對象
source.subscribe(new AutoDisposingObserverImpl<>(scope, observer));
}
創建AutoDisposingObserverImpl實例,並接着調用該實例的onSubscribe、onNext方法.
final class AutoDisposingObserverImpl<T> extends AtomicInteger implements AutoDisposingObserver<T> {
//lifecycleDisposable ->
private final AtomicReference<Disposable> lifecycleDisposable = new AtomicReference<>();
AutoDisposingObserverImpl(Maybe<?> lifecycle, Observer<? super T> delegate) {
//lifecycle -> Maybe<LifecycleEndNotification>
this.lifecycle = lifecycle;
//delegate實際上爲observer,因爲在AutoDisposingObserverImpl代理了Observable的調用
//所以此處命名爲deletagete
this.delegate = delegate;
}
@Override public void onSubscribe(final Disposable d) {
//創建一個Observer對象
DisposableMaybeObserver<Object> o = new DisposableMaybeObserver<Object>() {
@Override public void onSuccess(Object o) {
lifecycleDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposableHelper.dispose(mainDisposable);
}
@Override public void onError(Throwable e) {
lifecycleDisposable.lazySet(AutoDisposableHelper.DISPOSED);
AutoDisposingObserverImpl.this.onError(e);
}
@Override public void onComplete() {
lifecycleDisposable.lazySet(AutoDisposableHelper.DISPOSED);
// Noop - we're unbound now
}
};
//設置lifecycleDisposable爲前面創建的Observer對象o
if (AutoDisposeEndConsumerHelper.setOnce(lifecycleDisposable, o, getClass())) {
//代理delegate的onSubscribe方法回調
delegate.onSubscribe(this);
//調用Maybe<LifecycleEndNotification>::subscribe方法
lifecycle.subscribe(o);
AutoDisposeEndConsumerHelper.setOnce(mainDisposable, d, getClass());
}
}
}
在AutoDisposingObserverImpl::onSubscribe的實現中,主要完成了以下事情:
- 創建了DisposableMaybeObserver對象並賦值給成員lifecycleDisposable
- 代理consumer的onSubscribe方法調用
- 執行Maybe<LifecycleEndNotification>的訂閱
在ScopeUtil::deferredResolvedLifecycle方法中生成的Maybe<LifecycleEndNotification>對象如下:
Maybe.defer(new Callable<MaybeSource<? extends LifecycleEndNotification>>() {
@Override public MaybeSource<? extends LifecycleEndNotification> call() throws Exception {
//provider -> AndroidLifecycleScopeProvider
//lastEvent -> 對應LifecycleOwner的當前生命週期
E lastEvent = provider.peekLifecycle();
E endEvent;
try {
//provider -> AndroidLifecycleScopeProvider
//provider.correspondingEvents() -> DEFAULT_CORRESPONDING_EVENTS
//endEvent -> 匹配當前生命週期的結束生命週期,如ON_CREATE對應ON_DESTROY
endEvent = provider.correspondingEvents()
.apply(lastEvent);
} catch (Exception e) {
if (checkEndBoundary && e instanceof LifecycleEndedException) {
Consumer<? super OutsideLifecycleException> handler
= AutoDisposePlugins.getOutsideLifecycleHandler();
if (handler != null) {
handler.accept((LifecycleEndedException) e);
return Maybe.just(LifecycleEndNotification.INSTANCE);
} else {
throw e;
}
} else {
return Maybe.error(e);
}
}
//provider.lifecycle() -> LifecycleEventsObservable
//resolveScopeFromLifecycle -> 生成最終訂閱的Maybe<LifecycleEndNotification>對象,
//同時會對發生的事件進行過濾:skip(1) -> 跳過第一個數據,map -> 只匹配與endEvent相同的事件
return resolveScopeFromLifecycle(provider.lifecycle(), endEvent);
}
});
Maybe.defer只有在訂閱之後纔會創建相應的MaybeSource對象.在訂閱時首先調用call回調,主要完成以下任務:
1.調用AndroidLifecycleScopeProvider::peekLifecycle方法,獲取當前lifecycle的生命週期lastEvent
2.調用provider.correspondingEvents().apply(lastEvent)
獲取對應lastEvent的結束生命週期endEvent
3.生成Maybe<LifecycleEndNotification>對象,該對象對LifecycleEventsObservable進行包裝之後再交由DisposableMaybeObserver訂閱
我們先來看看LifecycleEventsObservable的實現:
class LifecycleEventsObservable extends Observable<Event> {
private final Lifecycle lifecycle;
@Override protected void subscribeActual(Observer<? super Event> observer) {
ArchLifecycleObserver archObserver =
new ArchLifecycleObserver(lifecycle, observer, eventsObservable);
observer.onSubscribe(archObserver);
if (!isMainThread()) {
.....
}
//此處對Lifecycle進行了監聽.
lifecycle.addObserver(archObserver);
if (archObserver.isDisposed()) {
lifecycle.removeObserver(archObserver);
}
}
//用於監聽生命週期的Observer子類
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(LifecycleOwner owner, Event event) {
if (!isDisposed()) {
//此處過濾掉重複的CREATE event
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);
}
//observer -> DisposableMaybeObserver對象
observer.onNext(event);
}
}
}
}
隨後看看resolveScopeFromLifecycle函數對LifecycleEventsObservable進行了什麼操作:
public static <E> Maybe<LifecycleEndNotification> resolveScopeFromLifecycle(
Observable<E> lifecycle,
final E endEvent) {
return lifecycle.skip(1)
.map(new Function<E, Boolean>() {
@Override public Boolean apply(E e) throws Exception {
return e.equals(endEvent);
}
})
.filter(IDENTITY_BOOLEAN_PREDICATE)
.map(TRANSFORM_TO_END)
.firstElement();
}
首先,skip掉了Observable發處的第一個數據,因爲這通常對應LifecycleOwner的初始化生命週期,所以並不會影響進行dispose的時機。隨後,篩選出與endEvent一致的事件讓其通過,比如在onCreate進行訂閱則endEvent爲ON_DESTROY.最後對事件名稱進行了下映射並返回滿足條件的第一個事件.
這裏需要對firtstElement操作符進行說明,調用firtstElement封裝後的Observable子類會對下發的數據進行計數。當計數到達特定下標時,這裏對應0,則認爲數據派發已經完成隨後調用s.dispose()
.對應的代碼實現如下:
public void onNext(T t) {
if (done) {
return;
}
long c = count;
if (c == index) {
done = true;
//上流的Observable對象
s.dispose();
//actual -> observer對象,這裏指代DisposableMaybeObserver實例
actual.onSuccess(t);
return;
}
count = c + 1;
}
s爲上流的Observable對象,由於rxjava支持鏈式調用,故每個Observable都會以引用的方式引用上流的Observable對象.s.dispose
會回調至LifecycleEventsObservable::onDispose
方法取消對lifecycle的監聽.隨後,actual.onScucess
會回調至DisposableMaybeObserver::onSuccess
方法,如下:
final class AutoDisposingObserverImpl<T> extends AtomicInteger implements AutoDisposingObserver<T> {
DisposableMaybeObserver<Object> o = new DisposableMaybeObserver<Object>() {
@Override public void onSuccess(Object o) {
//銷燬observer本身
lifecycleDisposable.lazySet(AutoDisposableHelper.DISPOSED);
//mainDisposable -> 在本文中對應由Observable.create創建的ObservableCreate實例,此處進行銷燬
AutoDisposableHelper.dispose(mainDisposable);
}
}
}
在onSuccess回調中,主要做了兩件事:
- 銷燬自身對應的DisposableMaybeObserver實例
- 銷燬上游的Observable對象,由於AutoDisposingObserverImpl作爲observer保存在上游的Observable中,在調用Observable::dispose時會同時銷燬observer成員.故AutoDispose完成了在生命週期結束時對Observable和Observer相應的實例銷燬,從而避免了內存泄漏.