我有一个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