2016-02-06 8 views
7

Ho un'app per Android in cui ho un'attività e una pila di frammenti.NullPointerException correlato a FragmentManager.popBackStack. Come risolvere?

Utilizzando Crashlytics, ho ricevuto una singola istanza di quanto segue Exception:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.FragmentManager.popBackStack(java.lang.String, int)' on a null object reference 
     at com.company.app.Fragment$7$2.onClick(Fragment.java:397) 
     at android.view.View.performClick(View.java:5197) 
     at android.view.View$PerformClick.run(View.java:20926) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:145) 
     at android.app.ActivityThread.main(ActivityThread.java:5942) 
     at java.lang.reflect.Method.invoke(Method.java) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 

Il codice che sta producendo questo errore è:

okButton.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     dialog.dismiss(); 
     // The next line produces the Exception 
     getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       // Other code... 
     }, 250); 
    } 
}); 

Sulla base del test che ho fatto con questo app, l'utente per il quale si è verificata questa eccezione e il fatto che si è verificato solo una volta, sto pensando che questo Exception si verifica quando si verifica qualche strano consolidamento delle circostanze. (Fondamentalmente, non riesco a riprodurre questo Exception sul mio lato.) Sto assumendo che questo abbia a che fare con l'utente che esegue lo sfondo della mia app e quindi riprenderlo in un secondo momento, e quindi la chiamata getFragmentManager() restituisce un null.

Quindi, io so che posso "risolvere" questo con il codice come il seguente (trovato questo come una correzione applicata ad un repository GitHub):

FragmentManager fm = getFragmentManager(); 
if (fm != null) fm.popBackStack(); 

Mentre mi rendo conto che il codice di cui sopra sarà "risolvere "il problema in quanto eviterà il NPE, (bloccando quindi l'arresto anomalo dell'app), non risolverà il problema in realtà consentendo alla mia app di funzionare come desiderato. La Fragment in questione è # 3 in una pila di frammenti, in questo modo:

#1 --> #2 --> #3 

il comportamento desiderato per l'applicazione è di rispondere a questo pulsante scatto da popping torna a Fragment # 1 è visibile. Aggiungere semplicemente il codice sopra sembra come se potesse impedire all'app di arrestarsi in modo anomalo, ma non modificare l'interfaccia utente dell'app nel modo desiderato.

Cosa sto facendo di sbagliato in modo tale che quando la mia app riprende, è "framment state" è fuori questione?

+1

Ho lo stesso identico problema, chiamo getFragmentManager(). PopBackStack() su un pulsante per chiudere il frammento e tornare a quello precedente. Inoltre non riesco a riprodurlo ma il bug è abbastanza frequente da costituire un problema reale. –

+0

sto affrontando questo problema ora hai trovato una soluzione ?? –

risposta

0

Non ho mai riscontrato un problema con getFragmentManager() come null, quindi presumo che sia la parte popBack dell'istruzione a causare il problema. Ecco una possibile soluzione per prevenire un arresto anomalo e gestire le eccezioni. Se fosse successo solo una volta, potrebbe essere stato un caso raro.

okButton.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     if (getSupportFragmentManager() != null) { 
      // Assuming the getFragmentManager() is not the Issue, rather the popBackStack is the issue 
      try { 
       getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
      } catch (Exception e) { 
       // Recreate a new instance of your first fragment here. 
      } 
     } else { 
      /* 
      getFragmentManager() == null 
      I have never faced an issue when getFragmentManager() == null, but I would restart the activity if that is the case 
      */ 

     } 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 

      } 
     }, 250); 
    } 
});