【问题标题】:Retrofit + RxJava - Not emitting when Fragment is restored, if I used Disposable.dispose()Retrofit + RxJava - 如果我使用 Disposable.dispose(),恢复 Fragment 时不发射
【发布时间】:2018-09-25 20:17:35
【问题描述】:

我有一个 Fragment A,它使用 Retrofit 调用 onCreateView 中的 API。
结果将用于显示对象列表。

Fragment A 还有一个按钮可以导航到Fragment B,通过提交FragmentTransaction 并替换自身。 (Fragment AonDestroyView 触发)

一切正常,但是当我从Fragment B 回到Fragment AFragment AonCreateView 触发)时,API 没有被调用。

只有当我在onDestroyView 中调用Disposable.dispose() 时才会发生这种情况,这是为了防止内存泄漏。

我的期望

由于每次触发onCreateView 时都会创建新的Observables,因此它们应该独立于先前处置的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);
                    }
                });
        ...
    }

    ...
}

基本片段:

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,但产生了相同的结果。

【问题讨论】:

    标签: android android-fragments retrofit rx-java2


    【解决方案1】:

    刚刚发现我应该使用Disposable.clear() 而不是dispose()dispose() 让我无法再将Disposable 添加到同一个CompositeDisposable

    一个有趣的事实是,RxLifecycle 产生了同样的问题。这是否意味着他们使用dispose() 而不是clear()

    EDIT@2018-04-20

    RxLifecycle可以参考this Github issue

    【讨论】:

    • 我遇到了同样的问题 ;) 感谢您找到解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    相关资源
    最近更新 更多