2017-07-03 5 views
0

Ich stehe vor der berühmten IllegalStateException Problem in meiner App. Das Problem tritt auf, nachdem eine Netzwerkanforderung (unter Verwendung von Retrofit) ausgeführt wurde, und gab mir eine Observable zurück. ich die hervorragende Mosby-Framework MVP Sachen zu behandeln, hier ist mein Code:Disposable Observables in onDettachView

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()); 
      } 
     } 
    } 

Die Ausnahme ich von Crashlytics bekommen ist:

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) 

Meine Fragen: es ist richtig Observables in der detachView-Methode zu entsorgen? Von was ich verstehe, wird die detachView aufgerufen, wenn der frag (ich benutze es mit frags) onDestroyView aufgerufen wird, direkt nach onStop (wo der Status von Android überprüft wird). Wenn nicht, sollte ich eine dispose-Methode in meinem Presenter erstellen und sie von meinem frag onStop aufrufen?

Danke!

+0

Ehrlich gesagt denke ich, Sie haben nicht viele Optionen. Ich hatte das gleiche Problem. Die fragment destroy Ansichtsmethode wurde nicht aufgerufen, obwohl wir '' replace'' anstelle von '' add'' verwendet haben. Ich bin mir nicht ganz sicher, aber ich denke, dass dies mit appcompat-Aktivitäten zusammenhängt, die uns eine Menge Ärger ersparen und viele Dinge mit Fragmenten behandeln, die wir nicht kümmern müssen. Ich habe die Methoden "onStart" und "onStop" aus dem Fragment enthüllt, damit ich die Daten richtig entsorgen und abfragen kann. – Fred

Antwort

0

Ich denke, detachView() ist das richtige Ereignis zu entsorgen, wenn Sie bei onStop() verfügen würde - wo auch immer Ihre Aktivität gestoppt die Abfrage abgebrochen wird. Von UX-Perspektive bedeutet das, dass wenn der Benutzer eine Abfrage gestartet hat, dann einen Anruf erhalten hat oder zu einer anderen App gewechselt ist und zurückkommt, wird die Abfrage nicht fortgesetzt und er muss sie erneut auslösen und in der App warten.

wie für dieses Problem, auch wenn Sie bei onStop() entsorgen, wird es das Problem nicht lösen, wie onSaveInstanceState() vor onStop() aufgerufen wird.

Dies ist ein allgemeines gemeinsames Fragment Problem, wenn Sie Fragment Transaktion nach onSaveInstance(), begehen und auf Fragmenten Ebene gelöst werden sollen, können Sie hier verschiedene Lösungen sehen, wie commitAllowingStateLoss() zum Beispiel mit:
IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager