0

Das folgende ist mein Stack-Trace:Diese Aktion kann nicht nach onSaveInstanceState ausführen

Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493) 
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511) 
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:634) 
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613) 

Dies ist mein Code:

dialog = FeedDialog.getInstance(feedViewModels, this, false, this); 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     if (fragmentManager != null && !isFinishing()) { 
      FragmentTransaction ft = fragmentManager.beginTransaction(); 
      ft.add(R.id.fragment_content, dialog); 
      ft.addToBackStack("unread_feeds"); 
      ft.commit(); 
      fragmentManager.executePendingTransactions(); 
     } 

Hier Dialog ist ein Fragment, das eine Ansicht Pager enthält.

Das Problem wird nur ein einziges Mal erschienen. Lass mich wissen, wie ich es beheben kann.

Antwort

0

IllegalStateException tritt auf, wenn Sie eine Methode zu einem ungeeigneten Zeitpunkt aufrufen.

Eine sehr häufige Art und Weise, wenn dies angezeigt ist, wo Sie ein Netzwerk Anruf, rufen und ein Fragment Transaktion in der Callback auslösen. Wenn die App minimiert, wenn das Netzwerk Aufruf abgeschlossen ist, sollten Sie eine IllegalStateException bekommen. Ich denke, Sie sollten diese Transaktion in einigen async Rückruf durchführen.

Lösung ist eine isResumed() Prüfung vor dem Ausführen der Transaktion hinzufügen. Wenn isResumed() false zurückgibt, müssen Sie die Transaktion in die Warteschlange auftreten, nachdem App wieder aufgenommen wird. Sie können in Ihrem Fragment (oder BaseFragment) eine Hilfsmethode verwenden, die eine Liste von Runnable-Objekten verwaltet und sie in onResume ausführt.

List<Runnable> pendingJobsOnResume; 
public void executeOnResume(Runnable runnable) { 
    if (isResumed()) { 
     runnable.run(); 
    } else { 
     pendingJobsOnResume.add(runnable); 
    } 
} 

// And invoke them in onResume 
void onResume() { 
    super.onResume(); 
    for (Runnable runnable : pendingJobsOnResume) { 
     runnable.run(); 
    } 
    pendingJobsOnResume.clear(); 
} 

Dann in Ihren Rückruf, können Sie den Transaktionscode durch einen runnable zu executeOnResume anstatt direkt aufrufen übergeben.

someAsyncTask(new Callback() { 
    void call() { 
     // do common stuff. 

     executeOnResume(new Runnable() { 
      void run() { 
       // fragment transaction 
      } 
     }) 
    } 
}