35 votes

provoquant un java. Erreur illegalStateException, Pas d'activité, uniquement lors de la navigation vers Fragment pour le temps SECOND

Je suis très curieux bug que je n'ai aucune idée de comment même de commencer à travailler à travers.

J'ai une application simple avec une activité, les points de vue sont mis en œuvre avec des Fragments. L'un des fragments a un ViewPager à l'intérieur de celui-ci; j'ai donc décidé que je voulais utiliser le getChildFragmentManager classe de la v4 bibliothèque de prise en charge. J'ai également eu à utiliser ActionBarSherlock, qui a causé un problème, car il n'est pas livré avec la v11 de la v4 de la bibliothèque.

J'ai résolu ce problème en remplaçant la v4 bibliothèque de prise en charge en ABS avec la v11 de la bibliothèque, et tout compilé et semblait être de travail, y compris la ViewPager.

Ici est la partie étrange:

La première fois que le fragment avec le ViewPager s'ouvre, il fonctionne correctement, mais la DEUXIÈME fois, il est à utiliser pour la navigation, l'application se bloque, donnant un inutile trace de la pile. À partir de débogage, j'ai découvert que le problème était avec la FragmentManager retourné par getChildFragmentManager; il jette en l'Absence d'Activité d'erreur.

Quelqu'un at-il une idée de ce que pourrait être la cause?

Je vais poster le code que vous jugez pertinente.

Merci, David

46voto

lopisan Points 1327

J'ai suivi le lien dans jeremyvillalobos réponse (qui a été très utile) qui m'a conduit à cette solution de contournement.

Il fonctionne pour moi bien, sans avoir besoin de réamédicer le fragment.

23voto

jeremyvillalobos Points 701

Cela semble être un bug signalé à

https://code.google.com/p/android/issues/detail?id=42601

La variable

FragmentManagerImpl mChildFragmentManager;

Dans Fragment.java n'est pas définie à null en détacher. Donc la prochaine fois que le fragment est chargé, la variable encore des points pour le dernier parent.

Comme discuté sur ce thread, une solution de contournement consiste à retrouver le Fragment.

Dans mon cas, j'étais à la commutation entre les fragments dans une ActionBar onglet. La difficulté Fragment a imbriquées Fragments et a été plantage de l'application lors de l'entrée dans le fichier loader Fragment. Donc, c'est le travail autour de code:

class MainTabsListener implements ActionBar.TabListener {
    public Fragment fragment;
    public int TabPosition;

    public MainTabsListener(Fragment fragment, int tab_position) {
        this.fragment = fragment;
        TabPosition = tab_position;
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        CurrentFragment = fragment;
        CurrentTabSelectedPos = TabPosition;

        /**
         * This is a work-around for Issue 42601
         * https://code.google.com/p/android/issues/detail?id=42601
         * 
         * The method getChildFragmentManager() does not clear up
         * when the Fragment is detached.
         */
        if( fragment instanceof FileLoaderFragment ){
            fragment = reinstatiateFileLoaderFragment();
        }

        ft.replace(R.id.fragment_container, fragment);

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(fragment);
    }

}

4voto

Kevin Liu Points 23

malheureusement, c'est un bug de soutien v4, toujours là :(

Lorsque vous choisissez d'autres Fragment via la Navigation Tiroir ou autre chose comme ça, le fragment qui a sous-fragments est détachée. Si ces sous-fragments fragmentManager(getChildFragmentManager()) n'existent plus. alors que ces fragments de retour, erreur s'est produite. De la bombe!

De toute évidence, le soutien v4 devez nettoyer mChildFragmentManager dans onDetach(), mais il n'a pas, donc, nous devons compter sur nous-mêmes. comme les codes suivants dans le fragment qui a sous-fragments:

@Override
    public void onDetach() {
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        super.onDetach();
    }

Tout sera OK, bonne journée :)

2voto

dmnlk Points 345

peut votre erreur est android.view.InflateException?

si oui, vous devriez gonfler Fragment dynamiquement, n'utilisez pas la mise en page XML.

et, vous ne devez pas cibler le fragment qui est défini XML Layout à Fragment Transaction.

2voto

Chtiboss Points 21

J'ai le même problème.

Dans une activité, j'ai 3 bouttons pour passer fragment de la transaction.remplacer(...)

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.layout_tablet_paneau, mLigneMessageFragment);

L'un de ce fragment contient un ViewPage avec une coutume FragmentPagerAdapter. Donc, je dois faire getChildFragmentManager(), admis à imbriquée Fragments.

le constructeur est ici:

public LignePagerAdapter(Fragment ligneMessageTabletFragment) {
        super(ligneMessageTabletFragment.getChildFragmentManager());
    }

Donc, j'ai le même message d'erreur: Le premier spectacle de ce fragment wrorks, mais quand je montre de l'autre fragment et de revenir sur celui-ci, j'ai cette exception:

02-26 11:57:50.798: D/ACRA(776): en Attente de pain grillé + travailleur terminé. Tuer Application ? vrai
02-26 11:57:50.798: E/AndroidRuntime(776): FATAL EXCEPTION: les principales
02-26 11:57:50.798: E/AndroidRuntime(776): java.lang.IllegalStateException: Aucune activité
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1861)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.Le Fragment.performActivityCreated(Fragment.java:1474)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.BackStackRecord.exécuter(BackStackRecord.java:682)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.de soutien.v4.app.FragmentManagerImpl$1.exécuter(FragmentManager.java:429)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.os.Gestionnaire d'.handleCallback(Handler.java:587)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.os.Gestionnaire d'.dispatchMessage(Handler.java:92)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.os.Looper.boucle(Looper.java:132)
02-26 11:57:50.798: E/AndroidRuntime(776): au android.app.ActivityThread.principale(ActivityThread.java:4126)
02-26 11:57:50.798: E/AndroidRuntime(776): à java.lang.de réfléchir.La méthode.invokeNative(Native method)
02-26 11:57:50.798: E/AndroidRuntime(776): à java.lang.de réfléchir.La méthode.invoke(la Méthode.java:491)
02-26 11:57:50.798: E/AndroidRuntime(776): au com.android.interne.os.ZygoteInit$MethodAndArgsCaller.exécuter(ZygoteInit.java:844)
02-26 11:57:50.798: E/AndroidRuntime(776): au com.android.interne.os.ZygoteInit.principale(ZygoteInit.java:602)
02-26 11:57:50.798: E/AndroidRuntime(776): à dalvik.système.NativeStart.principale(Native method)
02-26 11:57:52.818: I/dalvikvm(776): threadid=4: réaction de signal 3
02-26 11:57:52.818: I/dalvikvm(776): Écrit les traces de pile dans '/data/anr/traces.txt'

Ainsi, au lieu de mettre le même exemple de fragment, je peux re-créer pour résoudre le problème, mais je ne semblent pas efficaces.

transaction.replace(R.id.layout_tablet_paneau, LigneMessageTabletFragment.newInstance());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X