私はPresenterのインスタンスを作成するアクティビティを持っています。 Presenterレイヤーでは、リポジトリからObservableのインスタンスを取得しています。次に、サブスクライバのサブクラスを使用してObservableにサブスクライブし、結果のSubscriptionオブジェクトをCompositeSubscriptionに追加します。 SubscriberのonNext()が呼び出されるとActivityを変更する必要があるため、PresenterのリファレンスもSubscriberに渡します。Android、RxJava、MVP、メモリリーク
ここでは、参照がどのように機能し、ガベージコレクションの対象となるのかとその理由を知りたいと思います。
例1: ObservableはSubscriberを使用してサブスクライブされ、サブスクリプションはCompositeSubscriptionに追加されます。サブスクライバのonNext()が呼び出される前に、親アクティビティはそのonPause()ライフサイクルイベントをヒットします。 PresenterはComposerSubscriptionでonPause()を呼び出し、Presenterはclear()を呼び出します。この時点で、GCに適格なCompositeSubscription、SubscriberおよびObservableはありますか?または、PresenterのonPause()メソッドで、Observable、SubscriberおよびCompositeSubscriptionへの参照を明示的にnullにする必要がありますか?
例2)プレゼンターが観測に加入し、加入者のonNext()メソッドが呼び出される前に活動onPause(通過する)が、この時間は、それはまた(onResumeを通過例1に
同様。
例1と同様に、プレゼンターはonPause()のCompositeSubscriptionでclear()を呼び出します。
Presenterは以前にObservableをシングルトンクラスにキャッシュしていました。したがって、onResumeではObservableが実行を完了しなかったことを意味するキャッシュにObservableがあることがわかります。したがって、PresenterはSubscriberの新しいインスタンスとCompositeSubscriptionの新しいインスタンスを作成し、SubscriberおよびCompositeSubscriptionの新しいインスタンスを使用してキャッシュObservableにサブスクライブします。
しかし今私の質問は、私はメモリリークを導入している? Subscriberの最初のインスタンスにはPresenterへの参照があります。 onResume()が呼び出されると、私はSubscriberの2番目のインスタンスを作成し、Presenterはこの新しいインスタンスを参照します。では、Subscriberの最初のインスタンスはどうなりますか?それは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