我有一個Activity來創建Presenter的一個實例。在Presenter層中,我從存儲庫中獲取Observable的實例。然後我使用Subscriber的子類訂閱Observable,然後將生成的Subscription對象添加到CompositeSubscription。因爲我需要在訂閱者的onNext()被調用後修改Activity,所以我還將Presenter的引用傳遞給訂閱者。Android,RxJava,MVP和內存泄漏
現在我想知道引用是如何工作的,什麼時候符合垃圾回收的條件。
示例1: Observable使用訂閱者進行訂閱,訂閱被添加到CompositeSubscription。在訂購者的onNext()可以被調用之前,父活動會觸及其onPause()生命週期事件。它告訴Presenter打onPause()並且Presenter在CompositeSubscription上調用clear()。
此時是CompositeSubscription,Subscriber和Observable符合GC的條件嗎?或者在Presenter的onPause()方法中,我是否需要顯式地將對Observable,Subscriber和CompositeSubscription的引用歸零?
實施例2:
類似於實施例1演示預訂可觀察到的和訂戶的onNext()方法被調用活動經過的onPause(),但此時它也經過的onResume()之前。
因此,就像在示例1中,Presenter在onPause()的CompositeSubscription上調用clear()。
然後在onResume中發生以下情況: Presenter先前在單例類中緩存了Observable,因此在onResume中可以看到緩存中存在Observable,意味着Observable從未完成運行。因此,Presenter現在創建一個Subscriber的新實例和一個CompositeSubscription的新實例,並使用Subscriber和CompositeSubscription的新實例訂閱緩存的Observable。
但現在我的問題是,我介紹了內存泄漏?訂閱者的第一個實例提供了Presenter。當onResume()被調用時,我創建了Subscriber的第二個實例,並且Presenter引用了這個新實例。那麼訂閱者的第一個實例會發生什麼?它是否有資格使用GC或者是否因爲它引用了演示者而沒有引用指向它的內存泄漏?
class Presenter {
private MyActivity mActivity;
private Repository mRepository;
private GlobalCache mGlobalCache;
private CompositeSubscription mCompSub;
public Presenter(MyActivity activity, Repository repository, GlobalCache globalCache) {
mActivity = activity;
mRepository = repository;
mGlobalCache = globalCache;
}
public void doLongRunningThing() {
Observable<Object> obs = mRepository.getObs();
mGlobalCache.retain(obs);
mCompSub = new CompositeSubscription();
MySubscriber subscriber = new Subscriber(this);
compSub.add(obs.subscribe(subscriber));
}
public void onResume() {
if (mGlobalCache.getObs() != null) {
Observable<Object> obs = mGlobalCache.getObs();
mCompSub = new CompositeSubscription();
MySubscriber subscriber = new Subscriber(this);
compSub.add(obs.subscribe(subscriber));
}
}
public void onPause() {
if(mCompSub != null && mCompSub.hasSubscriptions()) {
mCompSub.clear();
}
}
public void onDestroy() {
mActivity = null;
mRepository = null;
mGlobalCache = null;
}
public void handleResponse(Object object) {
activity.setUiToSomeState();
}
}
class MySubscriber extends Subscriber<Object> {
private Presenter mPresenter;
private GlobalCached mGlobalCache;
public MySubscriber(Presenter presenter, GlobalCache globalCache) {
mPresenter = presenter;
mGlobalCache = globalCache;
}
onCompleted() {
}
onError() {
}
onNext(Object object) {
mGlobalCache.clearObs();
mPresenter.handleResponse(object);
}
}
我的主要掛在這裏是參考樹,並不理解垃圾收集器如何確定是否符合GC的條件時爬取樹。你的回答是正確的。 – neonDion