[英]Disposing Observables in onDettachView
I'm facing the famous IllegalStateException problem in my app. 我在应用程序中遇到著名的IllegalStateException问题。 The problem stems after a network request (using Retrofit) is done, returning me an Observable.
问题发生在完成网络请求(使用翻新)后,返回一个Observable。 I'm using the excellent Mosby framework to handle MVP stuff, here is my code:
我正在使用出色的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());
}
}
}
The exception I'm getting from Crashlytics is: 我从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)
My questions: Is it right to dispose Observables in the detachView method ? 我的问题:在detachView方法中放置Observables是否正确? From what I understand, the detachView is called when the frag (I'm using it with frags) onDestroyView is called, right after onStop (where the state gets checked by Android).
据我了解,当onStop(Android会检查状态)之后,在调用碎片(我在碎片中使用它)onDestroyView时会调用detachView。 If not, should I create a dispose method in my presenter and call it from my frag onStop ?
如果没有,我是否应该在演示者中创建一个dispose方法并从我的片段onStop调用它?
Thanks ! 谢谢 !
I think detachView()
is the correct event to dispose, if you would dispose at onStop()
- where ever your activity stopped the query will cancelled. 我认为
detachView()
是要处理的正确事件,如果您要在onStop()
处进行处理-无论您的活动停止在哪里,查询都将被取消。 from UX perspective, that's means that if user started a query, then got a phone call, or switch to another app and comes back, the query will not continue and he must trigger it again and wait inside the app. 从UX的角度来看,这意味着如果用户启动了查询,接了电话或者切换到另一个应用并返回,则查询将不会继续,他必须再次触发它并在应用内等待。
as for this problem, even if you would dispose at onStop()
, it will not solve the problem as onSaveInstanceState()
is called before onStop()
. 对于此问题,即使您将其放置在
onStop()
,也不会解决问题,因为onSaveInstanceState()
会在onStop()
之前onStop()
。
This is a general common Fragments issue, when you commit fragment transaction after onSaveInstance()
, and should be solved at Fragments level, you can see here various solutions, like using commitAllowingStateLoss()
for instance: 这是一个常见的常见Fragments问题,当您在
onSaveInstance()
之后提交片段事务时,应在Fragments级别解决,您可以在此处看到各种解决方案,例如使用commitAllowingStateLoss()
:
IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager IllegalStateException:使用ViewPager在onSaveInstanceState之后无法执行此操作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.