8

上下文:我有一个Activitywith aFragment和 3 InnerFragments。当Fragment onDestroy()被调用时,我想从FragmentManager. 代码onDestroy()如下。

问题: FragmentManager throws 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)
4

3 回答 3

9

FragmentManager管理所有Fragments级别,并且它们的Activity生命周期将与该父级绑定Activity。子管理器在级别上Fragment管理所有内容,它们的生命周期将与该父级绑定。FragmentsFragmentFragment

因此,对于您的手机架构,请将您添加InnerFragment到您的Activityusing getFragmentManager(). 当Activity永久销毁时(通过后退按钮 / finish()),FragmentManager将销毁并InnerFragment为您释放。

对于您的平板电脑架构,请将您添加InnerFragments到您的Fragment使用中getChildFragmentManager()(在最新的支持库中)。当Fragment毁灭为善时,FragmentManager意志为你毁灭并释放InnerFragments

你不应该管理释放和摧毁你Fragments自己。我建议记录您的生命周期事件,Activities这样Fragments您就可以观察它们的状态并确保正确的行为。

于 2013-02-12T14:20:16.833 回答
1

NullPointerException 是由于 Activity 的 Handler 未从 FragmentManager 设置的事实引起的,因此可以防止崩溃的“解决方案”如下:

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) {

        }
}
于 2015-07-09T09:34:56.150 回答
0

案例:当您需要从另一个片段(父片段)调用片段(子片段)时

始终使用getChildFragmentManager()而不是getFragmentManager在您的父片段内。

阅读文档

于 2019-06-24T06:08:49.813 回答