3

Je reçois les rapports d'erreur suivants:Impossible d'effectuer cette action après onSaveInstanceState montrent

Exception fatale: java.lang.IllegalStateException: Impossible d'effectuer cette action après onSaveInstanceState à android.support.v4 .app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1832) à l'adresse android.support.v4.app.FragmentManagerImpl.enqueueAction (FragmentManager.java:1850) at android.support.v4.app.BackStackRecord.commitInternal (BackStackRecord.java : 643) at android.support.v4.app.BackStackRecord.commit (BackStackRecord.java:603) à android.support.v4.app.DialogFragment.show (DialogFragment.java:143)

Ce code suivant est à l'origine du crash, je coupe un code de configuration trivial pour plus de clarté. J'ai lu sur cette erreur et si je comprends bien le .show() devrait être en sécurité dans une interaction de l'utilisateur tels que onClick(). La seule chose que je peux penser est que le query() prend beaucoup de temps et l'utilisateur échange. Est-ce une explication logique pour cette erreur? C'est instantané sur mes appareils même avec une grande DB. D'autres possibilités? Merci!

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

Avez-vous trouvé la solution pour cette exception fatale. – RameshJaga

Répondre

0

Vous pouvez afficher une boîte de dialogue de progression jusqu'à ce que votre requête exécute et faire l'utilisateur d'attente sur l'écran et en même temps l'informer que quelque chose est en cours de traitement.

Ou si vous ne voulez pas informer l'utilisateur sur le traitement dans ce cas, vérifiez si l'activité est à l'avant-plan uniquement, puis affichez la boîte de dialogue.

Vous pouvez utiliser une variable booléenne isInForeground et la définir/réinitialiser dans onResume et respectivement.

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

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

wrap et la logique show de dialogue si l'état

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

Si ce code de la vôtre est dans une activité, enveloppez l'appel à show avec:

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

et si ce code est dans un fragment, envelopper l'appel à show avec:

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

Cette plus ou moins résoudrait la question de l'atterrissage dans un état de l'interface utilisateur incompatible

0

Plus je le regardais plus il me dérangeait que j'avais une requête dans le code de l'interface utilisateur. C'était probablement mon code initial pour tester le concept et je l'ai négligemment laissé quand ça a marché.

Il ya un LoaderManager pour l'application en utilisant la mauvaise requête, mais j'ai utilisé le onLoadFinished existant pour déclencher une requête asynchrone qui mettra à jour la structure du chemin sur toute modification de la base de données. Maintenant, lorsque l'utilisateur clique sur la boîte de dialogue est prêt à partir.

Puisque je ne peux pas reproduire l'erreur, il faudra environ une semaine avant que je puisse rendre un verdict sur celui-ci, mais de toute façon le code précédent était bâclé.

0

Il semble que votre activité soit en pause/votre application ne se trouve pas dans l'avant-plan. Vous pouvez faire une chose avant d'ajouter un fragment vérifier si votre activité ne soit pas détruit/finition et votre application est au premier plan (Il n'est pas réduite au minimum)

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

écrire du code pour vérifier si votre application est au premier plan ou non