上下文:我有Activity
Fragment
和3 InnerFragments
。调用Fragment
onDestroy()
后,我想从FragmentManager
中删除内部片段。 onDestroy()
的代码如下所示。
问题 FragmentManager
抛出NullPointerException
,可能是在调用commitAllowingStateLoss()
时。我不明白为什么。
@Override
public void onDestroy()
{
super.onDestroy();
if (getFragmentManager().findFragmentById(R.id.fragment_framelayout_left) != null)
{
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.remove(mLeftFragment);
fragmentTransaction.commitAllowingStateLoss();
}
}
堆栈跟踪:
02-11 12:15:14.162: E/AndroidRuntime(25911): FATAL EXCEPTION: main
02-11 12:15:14.162: E/AndroidRuntime(25911): java.lang.NullPointerException
02-11 12:15:14.162: E/AndroidRuntime(25911): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1419)
02-11 12:15:14.162: E/AndroidRuntime(25911): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
02-11 12:15:14.162: E/AndroidRuntime(25911): at android.os.Handler.handleCallback(Handler.java:725)
02-11 12:15:14.162: E/AndroidRuntime(25911): at android.os.Handler.dispatchMessage(Handler.java:92)
02-11 12:15:14.162: E/AndroidRuntime(25911): at android.os.Looper.loop(Looper.java:137)
02-11 12:15:14.162: E/AndroidRuntime(25911): at android.app.ActivityThread.main(ActivityThread.java:5039)
02-11 12:15:14.162: E/AndroidRuntime(25911): at java.lang.reflect.Method.invokeNative(Native Method)
02-11 12:15:14.162: E/AndroidRuntime(25911): at java.lang.reflect.Method.invoke(Method.java:511)
02-11 12:15:14.162: E/AndroidRuntime(25911): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-11 12:15:14.162: E/AndroidRuntime(25911): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-11 12:15:14.162: E/AndroidRuntime(25911): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:9)
FragmentManager
管理Fragments
级别的所有Activity
,其生命周期将与该父级Activity
相关联。子Fragment
经理管理Fragments
级别的所有Fragment
,其生命周期将与该父Fragment
相关联。
因此,对于您的手机架构,请使用InnerFragment
将Activity
添加到getFragmentManager()
。当Activity
销毁时(通过后退按钮/ finish()
),FragmentManager
会为您销毁并释放InnerFragment
。
对于平板电脑架构,请使用InnerFragments
(在最新的支持库中)将Fragment
添加到getChildFragmentManager()
。当Fragment
销毁时,FragmentManager
会销毁并释放InnerFragments
。
您不应该自己管理释放和销毁Fragments
。我建议您记录Activities
和Fragments
的生命周期事件,这样您就可以看到它们通过状态并确保正确行为。
答案 1 :(得分:1)
NullPointerException是由于FragmentManager中没有设置Activity的Handler这一事实引起的,所以防止崩溃的“解决方案”如下:
public void onDestroy(){
super.onDestroy();
try {
Field mActivityField = getFragmentManager().getClass().getDeclaredField("mActivity");
mActivityField.setAccessible(true);
mActivityField.set(getFragmentManager(), this);
Field mPendingActionsField = getFragmentManager().getClass().getDeclaredField("mPendingActions");
mPendingActionsField.setAccessible(true);
mPendingActionsField.set(getFragmentManager(), null);
Field f = Activity.class.getDeclaredField("mHandler");
f.setAccessible(true);
Handler handler = (Handler) f.get(this);
handler.close();
} catch (Throwable e) {
}
}
答案 2 :(得分:0)
案例:当您需要从另一个Fragment(父片段)调用Fragment(子片段)
在父片段中始终使用getChildFragmentManager()
而不是getFragmentManager
。