在onDettachView中处理Observable

时间:2017-07-03 02:13:32

标签: android rx-java2 mosby

我在我的应用中面临着名的IllegalStateException问题。问题源于网络请求(使用Retrofit)完成后,返回一个Observable。 我正在使用优秀的Mosby框架来处理MVP,这是我的代码:

public class CarAdPresenterCustomer extends CarAdPresenterAbstract {

    private final GetCarByIdUseCase getCarByIdUseCase;
    private final GetCarMatchDetailsUseCase getCarMatchDetailsUseCaseUseCase;

    public CarAdPresenterCustomer(GetCarByIdUseCase getCarByIdUseCase, GetCarMatchDetailsUseCase getCarMatchDetailsUseCaseUseCase) {
        this.getCarByIdUseCase = getCarByIdUseCase;
        this.getCarMatchDetailsUseCaseUseCase = getCarMatchDetailsUseCaseUseCase;
    }

    public void getCarMatchDetails(String carId) {

        if (isViewAttached()) {
            getView().showLoading();
        }
        getCarMatchDetailsUseCaseUseCase.execute(new GetCarMatchDetailsSubscriber(), new GetCarMatchDetailsUseCase.Params(carId));
    }

    public void getCarDetails(String carId) {
        getCarByIdUseCase.execute(new GetCarByIdSubscriber(), new GetCarByIdUseCase.Params(carId));
    }

    @Override
    public void detachView(boolean retainInstance) {
        getCarByIdUseCase.dispose();
        getCarMatchDetailsUseCaseUseCase.dispose();
        super.detachView(retainInstance);
    }

    private class GetCarByIdSubscriber extends DefaultObserver<DefaultCarResponse> {

        @Override
        public void onNext(DefaultCarResponse carResponse) {
            if (carResponse != null) {
                if (isViewAttached()) {
                    getView().hideLoading();
                    getView().inflateCarUiComponents(carResponse.getCar());
                }
            }
        }

        @Override
        public void onError(Throwable exception) {
            if (isViewAttached()) {
                getView().hideLoading();
                getView().showErrorMessage(exception.getMessage());
            }
        }
    }

我从Crashlytics获得的例外是:

Fatal Exception: java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.
       at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:145)
       at android.app.ActivityThread.main(ActivityThread.java:6843)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1884)
       at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1902)
       at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:650)
       at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)
       at android.support.v4.app.DialogFragment.show(DialogFragment.java:143)
       at br.com.moobie.android.emailConfirmation.ui.fragment.EmailConfirmationFragment.showEmailConfirmationError(EmailConfirmationFragment.java:202)
       at br.com.moobie.android.emailConfirmation.presenter.EmailConfirmationPresenterImpl$GetUserSubscriber.onNext(EmailConfirmationPresenterImpl.java:75)
       at br.com.moobie.android.emailConfirmation.presenter.EmailConfirmationPresenterImpl$GetUserSubscriber.onNext(EmailConfirmationPresenterImpl.java:63)
       at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
       at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
       at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:145)
       at android.app.ActivityThread.main(ActivityThread.java:6843)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

我的问题: 在detachView方法中处理Observable是否正确? 根据我的理解,当onStop(Android被状态检查)之后调用frag(我正在使用frags)onDestroyView时调用detachView。 如果没有,我应该在演示者中创建一个dispose方法并从我的frag onStop调用它吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为detachView()是正确的处理事件,如果您要处置onStop() - 您的活动停止时,查询将被取消。从用户体验的角度来看,这意味着如果用户启动了查询,然后接到电话,或者切换到另一个应用程序并返回,查询将不会继续,他必须再次触发它并在应用程序内等待。 / p>

对于这个问题,即使您要处理onStop(),也不会解决问题,因为在onSaveInstanceState()之前调用了onStop()

这是一个常见的Fragments问题,当您在onSaveInstance()之后提交片段事务,并且应该在Fragments级别解决时,您可以在这里看到各种解决方案,例如使用commitAllowingStateLoss()
IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager