web-dev-qa-db-fra.com

Essayez d'appeler la méthode virtuelle 'Android.os.Handler Android.support.v4.app.FragmentHostCallback.getHandler ()' sur une référence d'objet null

Mon application consiste en 4 fragments sous forme d'onglets chargés dans un fragment parent à l'aide de FragmentPagerAdapter.

Le problème vient du moment où j'exécute l'application, puis appuie de nouveau sur et rouvre l'application. Ce journal d'erreurs s'affiche:

FATAL EXCEPTION: main
Java.lang.NullPointerException: Attempt to invoke virtual method 'Android.os.Handler Android.support.v4.app.FragmentHostCallback.getHandler()' on a null object reference
    at Android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.Java:1949)
    at Android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.Java:1965)
    at Android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.Java:620)
    at Android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.Java:143)
    at Android.support.v4.view.ViewPager.setAdapter(ViewPager.Java:513)
    ...

la ligne de code à l'intérieur du fragment parent est:

viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);

et ViewPage et Adapter les deux ne sont pas nuls !!

Je dois mentionner que tout mon cycle de vie de Fragments est géré et que le problème de null se produit à l'intérieur de l'adaptateur !, et que le même adaptateur fonctionne correctement lorsque j'utilise une variable Activity comme parent au lieu de Fragment !!!

19
Mohsen Mirhoseini

Après de nombreuses recherches, il semble que ce soit un problème de bibliothèque de support:

Activité avec fragment et ViewPager crash sur la configuration changement
Bibliothèque de support Android version 24.1.0

J'ai aussi trouvé cette réponse, mais il semble inhabituel d'ajouter un drapeau à mon code:

Tentative d’appel de la méthode virtuelle «Android.os.Handler Android.support.v4.app.FragmentHostCallback.getHandler ()» sur un objet null

Je remplace la méthode finishUpdate de ma FragmentPagerAdapter comme ceci et le problème résolu pour le moment!

@Override
public void finishUpdate(ViewGroup container) {
    try{
        super.finishUpdate(container);
    } catch (NullPointerException nullPointerException){
        System.out.println("Catch the NullPointerException in FragmentPagerAdapter.finishUpdate");
    }
}

une meilleure réponse? s'il vous plaît, faites-moi savoir...

34
Mohsen Mirhoseini

Je sais qu'il est peut-être tard, mais voici ma stupide erreur que je n'ai pas vue tout de suite:

@Override
public void onStop() {
    super.onDestroy(); //I was calling the wrong super
}
4
Firecat

J'ai eu le même problème. Dans mon cas, le problème était que je ré-utilisais sans remarquer l'adaptateur de la dernière fois ouvert.

J'ai regardé dans la classe FragmentManager.Java qui envoie l'exception et sur la même ligne qui bloque dit: "Doit être appelé à partir du thread principal du fragment Host"

mon code était:

PagerAdapter adapter = MPageAdapter.getInstance(getSupportFragmentManager()); 
viewPager.setAdapter(adapter);

parce que j'utilisais mon PageAdapter comme un pont pour communiquer entre les fragments, j'ai utilisé un motif singleton. Cela a bien fonctionné pour moi mais une fois que j'ai répété cette structure dans une autre activité, j'ai eu la même exception. Et la raison en est que j'ai oublié de détruire le singleton de ma classe d'adaptateur à la fin de chaque utilisation.

@Override
protected void onDestroy() {
    MPageAdapter.Destroy();  //I forgot this one, that makes singleton = null;
    super.onDestroy();
}
3
user3884508

J'avais le même problème et cela était dû à la réutilisation de ViewPager par différentes instances d'un fragment. Une solution consistait à annuler l'adaptateur dans la méthode onDestroyView() du fragment.

@Override public void onDestroyView() {
    mViewPager.setAdapter(null);
    super.onDestroyView();
}

Le projet présentant le problème et la solution peut être trouvé ici .

3
sergej shafarenka

J'ai le même problème sur mon projet. Mais c'est de ma faute.

POURQUOI

J'appelle onBackPressed dans un rappel après que l'activité a appelé onDestroy ();

Parce que l'instance de mHost dans FragmentManager est définie sur null après onDestroy () appelé.

et lors de l'appel onBackPressed, il utilisera à nouveau l'instance mHost.

1
Liu Tom
@Override
public void onBackPressed() {
//     super.onBackPressed();
       finish();
}  

Remplace la onBackPressed dans l'activité ..
supprimer le super appel: super.onBackPressed
et appelez la fin.

0
varunjohn1990

J'utilisais la mauvaise référence d'activité pour aller chercher 

getSupportFragmentManager ()

Utiliser la bonne activité a corrigé le crash pour moi.

0
Varun Bhatia