3

zeigen ich folgende Fehlerberichte erhalten:Kann diese Aktion nicht durchführen, nachdem onSaveInstanceState

Fatal Exception: java.lang.IllegalStateException: Kann nicht führen diese Aktion nach onSaveInstanceState bei android.support.v4 .app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1832) bei android.support.v4.app.FragmentManagerImpl.enqueueAction (FragmentManager.java:1850) bei android.support.v4.app.BackStackRecord.commitInternal (BackStackRecord.java : 643) bei android.support.v4.app.BackStackRecord.commit (BackStackRecord.java:603) bei android.support.v4.app.DialogFragment.show (DialogFragment.java:143)

Dieser folgenden Code den Absturz verursacht, schneide ich aus Gründen der Klarheit einige triviale Setup-Code aus. Ich habe diesen Fehler gelesen und wie ich es verstehe, sollte die .show() innerhalb einer Benutzerinteraktion wie onClick() sicher sein. Das einzige, woran ich denken kann ist, dass die query() lange dauert und der Benutzer austauscht. Ist das eine vernünftige Erklärung für diesen Fehler? Es ist sofort auf meinen Geräten sogar mit großen DB. Irgendwelche anderen Möglichkeiten? Vielen Dank!

foldersButton.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      final List<String> paths = new ArrayList<>(); 

      try(Cursor c = getActivity().getContentResolver().query(Meta.CONTENT_URI, 
        new String[]{"DISTINCT " + Meta.PARENT}, null, null, 
        Meta.PARENT + " ASC")) 
      { 
       while (c != null && c.moveToNext()) 
       { 
        String path = c.getString(c.getColumnIndex(Meta.PARENT)); 

        // We place the excluded folders at the end 
        if (!mExcludedFolders.contains(path)) 
         paths.add(path); 
       } 
      } 

      [setup...] 

      int[] position = new int[2]; 
      foldersButton.getLocationOnScreen(position); 
      FolderDialog dialog = FolderDialog.newInstance(
        paths.toArray(new String[paths.size()]), 
        visible, 
        excluded, 
        position[0], 
        position[1]); 
      dialog.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.FolderDialog); 

      [setup...] 

      dialog.show(getFragmentManager(), TAG); 
     } 
    }); 
+0

haben Sie die Lösung für diese schwerwiegende Ausnahme gefunden. – RameshJaga

Antwort

0

können Sie entweder zeigen einen Fortschrittsdialog, bis Ihre Abfrage ausführt und die Benutzerwartezeit auf dem Bildschirm und zugleich ihm machen informieren, dass etwas verarbeitet wird.

Oder wenn Sie den Benutzer in diesem Fall nicht über die Verarbeitung informieren möchten, prüfen Sie, ob die Aktivität nur im Vordergrund ist, und zeigen Sie den Dialog an.

Sie können eine boolesche Variable isInForeground verwenden und in onResume bzw. setzen/zurücksetzen.

@Override 
    protected void onPause() { 
     super.onPause(); 
     isInForeground=false; 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     isInForeground=true; 
    } 

wickeln Dann Dialog zeigen Logik, wenn Bedingung

if(isInForeground){ 
    dialog.show(getFragmentManager(), TAG); 
} 
2

Wenn dieser Code von Ihnen innerhalb einer Aktivität ist, wickeln Sie den Anruf zu show mit:

if(!isDestroyed() && !isFinishing())

und wenn Dieser Code befindet sich in einem Fragment. Umschließen Sie den Anruf mit show mit:

if (isResumed() && !isRemoving())

Diese mehr oder weniger würde das Problem der Landung in einem inkonsistenten Zustand UI lösen

0

Je mehr ich es sah, je mehr sie mich gestört, dass ich eine Abfrage in UI-Code hatte. Dies war wahrscheinlich mein erster Code, um das Konzept zu testen, und ich verließ es sorglos, als es funktionierte.

Es gibt eine LoaderManager für die Anwendung, die die falsche Abfrage verwendet, aber ich habe die vorhandene onLoadFinished verwendet, um eine asynchrone Abfrage auszulösen, die die Pfadstruktur bei jeder Änderung an der Datenbank aktualisieren wird. Wenn der Benutzer jetzt klickt, ist der Dialog fertig.

Da ich den Fehler nicht reproduzieren kann, wird es eine Woche oder so sein, bevor ich ein Urteil über dieses treffen kann, aber so oder so war der vorherige Code schlampig.

0

Es scheint, dass Ihre Aktivität pausiert ist/Ihre App ist nicht im Vordergrund. Sie können eine Sache tun, bevor nicht zerstört ein Fragment überprüfen, ob Ihre Aktivität Hinzufügen/Finishing und Ihre Anwendung im Vordergrund (Es ist nicht minimiert)

if(!isDestroyed()&&!isFinishing()&&isAppInForground(this)){ 
//add your fragment 
} 

nehmen Code zu überprüfen, ob Ihre Anwendung im Vordergrund ist oder nicht

/** 
     * 
     * @param context 
     * @return boolean 
     * tells whether user is currently viewing app or not if not return false otherwise true 
     */ 
     public static boolean isAppInForground(Context context){ 
      boolean isInForeground = false; 
      ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 

       List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses(); 
       for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) { 
        if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { 
         for (String activeProcess : processInfo.pkgList) { 
          if (activeProcess.equals(context.getPackageName())) { 
           isInForeground = true; 
          } 
         } 
        } 
       } 

      return isInForeground; 
     } 
Verwandte Themen