2012-11-15 6 views
65

ich manchmal die folgende Ausnahme erhalten, wenn sie mit Fragmenten arbeiten:Android FragmentManager BackStackRecord.run werfen Nullpointer

FATAL EXCEPTION: main 
java.lang.NullPointerException 
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:591) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420) 
    at android.os.Handler.handleCallback(Handler.java:615) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4745) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 

Die Ausnahme tritt auf, wenn run() von BackStackRecord durch execPendingTransactions() genannt wird, wenn es versucht, ein Fragment aus dem Manager zu entfernen .

case OP_REMOVE: { 
    Fragment f = op.fragment; 
    f.mNextAnim = op.exitAnim; <---- 
    mManager.removeFragment(f, mTransition, mTransitionStyle); 
} 
break; 

Ich kann nicht scheinen, herauszufinden, was genau das verursacht? Ich denke, es hat mit dem Stapel von Fragmenten zu tun, die nicht direkt beim Entfernen von Fragmenten aufgeräumt werden.

Antwort

158

Beantwortung meiner Frage:

Diese Ausnahme ist (schließlich) geworfen, wenn Sie FragmentTransaction.remove(null); anrufen und FragmentTransaction.commit();

EDIT: Und auch, wie Zweimal eingekreist und shinyuX Punkt im Kommentar aus; wenn die show(null) oder add(null), attach(null) und detach(null) Methoden aufrufen und wahrscheinlich auch hide(null)

Nach commit() Aufruf, wird die Transaktion in der FragmentManager die Warteschlange gestellt werden. Wenn die Operation verarbeitet wird, nachdem Sie explizit FragmentManager.executePendingTransactions() aufrufen oder wenn der FragmentManager-Warteschlange-Thread es aufruft, löst es daher eine NullPointerException aus.

In meinem Fall war ich Fragmentstatus in einem globalen Objekt beibehalten. Dort habe ich überprüft, ob das Fragment sichtbar ist oder nicht, und dann sichtbare Fragmente entfernt. Aber weil ich eine neue FragmentActivity gestartet habe, wurden diese Zustände immer noch auf "True" gesetzt, während sie nicht sichtbar waren. Das ist also ein Konstruktionsfehler.

Abgesehen von der Behebung des Konstruktionsfehlers war die Lösung einfach: Überprüfen Sie, ob FragmentManager.findFragmentByTag() vor dem Entfernen des Fragments null zurückgegeben wurde.

+14

Gute Antwort - Dies half mir, mein eigenes Problem zu lösen. Beachten Sie, dass Sie beim Aufruf von FragmentTransaction.show (null), .hide (null) usw. nicht nur .remove (null) den gleichen Fehler erhalten. Hoffentlich hilft dies anderen ihr Problem aufzuspüren. –

+0

Danke @NickL ...... – hemu

+1

Hat mir sehr geholfen! Beachten Sie, dass es mit keiner Aktion fehlschlägt, die mit einem Nullfragment gesendet wird (in meinem Fall 'attach'' detach') – shinyuX

-2

Ich verwende kein Tag, um die Fragmente zu erstellen (sie funktionieren wie TabBar-Container).

So, es funktioniert, wenn Tab ändern, aber wenn ich zurück Button drücken, habe ich den gleichen Fehler.

Bei onDestroyView-Methode fand ich Fragment-Instanz mit FragmentManager # findFragmentById, aber FragmentManager # findFragmentByTag gibt null, sicher.

class MyFragment extends ListFragment { 

@Override 
public void onDestroyView() { 
    super.onDestroyView(); 

    if (this.mapFragment != null 
      && getFragmentManager().findFragmentById(
        this.mapFragment.getId()) != null) { 

     getFragmentManager().beginTransaction().remove(this.mapFragment) 
       .commit(); 
     this.mapFragment = null; 
    } 

} 
} 
+2

Warum muss mapFragment auf null gesetzt werden? –

+1

Eine Frage, die es zu beantworten gilt: - 'Warum muss mapFragment auf null gesetzt werden?' – nmxprime