0

我在我的应用程序中遇到了著名的 IllegalStateException 问题。问题源于网络请求(使用改造)完成后,返回给我一个 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 方法中处理 Observables 是否正确?据我了解,在 onStop(Android 检查状态)之后调用 frag(我将其与 frags 一起使用)onDestroyView 时调用 detachView。如果没有,我应该在我的演示者中创建一个 dispose 方法并从我的 frag onStop 调用它吗?

谢谢 !

4

1 回答 1

0

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

至于这个问题,即使你在处理onStop(),也不会像onSaveInstanceState()之前所说的那样解决问题onStop()

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

于 2017-07-03T08:12:47.820 回答