我有Fragment A
使用Retrofit来调用onCreateView
中的API
结果将用于显示对象列表。
Fragment A
还有一个导航到Fragment B
的按钮,通过提交FragmentTransaction
并替换自己。 (Fragment A
onDestroyView
已触发)
一切正常,但当我从Fragment B
回到Fragment A
(Fragment A
onCreateView
已触发)时,API不会被调用。
只有在Disposable.dispose()
中调用onDestroyView
时才会发生这种情况,这是为了防止内存泄漏。
由于每次触发Observable
时都会创建新的onCreateView
,因此它们应该与之前处置的Disposables
无关。因此将再次调用API并触发回调。应该刷新对象列表。
onCreateView
被触发,也会触发告诉Retrofit调用API的行。但是没有一个回调(包括.map()
)被触发。由于我也记录了网络流量,我很确定实际上没有进行任何网络通信。 看起来RxJava或Retrofit决定停止播放。
当然,如果我不使用Disposable.dispose()
,这可以避免。但我确实想防止内存泄漏
这样做的正确方法是什么?
片段A:
public class BeansFragment extends BaseFragment {
...
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
retrofit.getSomeBeans()
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new APIResponseObserver<List<Beans>>(this) {
@Override
public void onNext(List<Beans> beans) {
if (getContext() == null) return;
setupBeansList(beans);
}
});
...
}
...
}
BaseFragment:
public abstract class BaseFragment extends Fragment {
private CompositeDisposable compositeDisposable = new CompositeDisposable();
...
@Override
public void onDestroyView() {
compositeDisposable.dispose();
super.onDestroyView();
}
}
最重要的是,APIResponseObserver
负责添加一次性用品:
public abstract class APIResponseObserver<T> implements io.reactivex.Observer<T> {
private BaseFragment fragment;
public APIResponseObserver(BaseFragment fragment) {
this.fragment = fragment;
}
@Override
public void onSubscribe(Disposable d) {
if (fragment != null) fragment.addToCompositeDisposable(d);
}
@Override
public void onError(Throwable e) {
//...
}
@Override
public void onComplete() {
//...
}
}
我也试过使用RxLifecycle,但产生了相同的结果。
答案 0 :(得分:5)
刚刚发现我应该使用Disposable.clear()
代替dispose()
。 dispose()
让我无法再将Disposable
添加到同一CompositeDisposable
。
一个有趣的事实是,RxLifecycle会产生同样的问题。这是否意味着他们使用dispose()
代替clear()
?
对于RxLifecycle,您可以参考this Github issue。