2012-11-15 93 views
65

我有時片段工作時出現以下情況例外:的Android FragmentManager BackStackRecord.run拋出NullPointerException異常

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) 

BackStackRecordrun()通過execPendingTransactions()叫時,它試圖從管理工具中刪除片段時發生異常, 。

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

我似乎無法弄清楚究竟是什麼造成了這種情況?我認爲這與拆卸碎片時沒有正確清理碎片的後臺堆棧有關。

回答

158

回答我的問題:

這個例外是(最終)當你調用FragmentTransaction.remove(null);FragmentTransaction.commit();

編輯拋出:而且也一樣,兩次盤旋shinyuX在註釋中指出;調用show(null)add(null)attach(null)detach(null)方法時,大概也hide(null)

調用commit()後,該交易將在FragmentManager排隊。因此,在您顯式調用FragmentManager.executePendingTransactions()或當FragmentManager隊列線程調用該操作時正在處理該操作時,它會拋出NullPointerException

在我的情況下,我在全局對象中維護片段狀態。在那裏我檢查了片段是否顯示,然後刪除了可見的片段。但是因爲我開始了一個新的FragmentActivity,這些狀態在它們不可見時仍然設置爲true。所以這是一個設計錯誤。

除了修正設計錯誤,解決方法很簡單:在刪除片段之前檢查FragmentManager.findFragmentByTag()是否返回null

+14

好的答案 - 這幫助我解決了我自己的問題。有一件事要注意,當你調用FragmentTransaction.show(null),.hide(null)等,而不是僅僅.remove(null)時,你會得到同樣的錯誤。希望這能幫助其他人追蹤他們的問題。 –

+0

謝謝@NickL ...... – hemu

+1

幫了我很多!請注意,它會失敗,任何動作與一個空片段發送(在我的情況下'attach'' detach' – shinyuX

-2

我不使用標籤來創建片段(它們像TabBar容器一樣工作)。

所以,它改變Tab時,但如果我按回按鈕,我得到了同樣的錯誤。

在onDestroyView方法中,我找到了帶有FragmentManager#findFragmentById的片段實例,但FragmentManager#findFragmentByTag肯定返回null。

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

爲什麼需要將mapFragment設置爲null? –

+1

一個值得回答的問題: - 爲什麼需要將mapFragment設置爲null?' – nmxprime

相關問題