仅由4.0.3(冰淇淋三明治)设备上的空指针异常,由FragmentManager.Impl.removeFragment引起

时间:2014-09-20 18:27:35

标签: android android-fragments nullpointerexception fragmentmanager

我的应用程序在4.0.3以上的所有Android版本上运行良好,但是当我在4.0.3上运行时,由于删除片段时出现空指针异常,它会强制关闭。堆栈跟踪没有指向任何特定的代码行,我不知道为什么在4.0.3设备上删除片段时它会返回null。

堆栈跟踪

09-20 13:50:17.541: E/AndroidRuntime(2152): FATAL EXCEPTION: main
09-20 13:50:17.541: E/AndroidRuntime(2152): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.fsck.k9/com.fsck.k9.activity.MessageList}: java.lang.NullPointerException
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.os.Looper.loop(Looper.java:137)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.ActivityThread.main(ActivityThread.java:4424)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at java.lang.reflect.Method.invokeNative(Native Method)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at java.lang.reflect.Method.invoke(Method.java:511)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at dalvik.system.NativeStart.main(Native Method)
09-20 13:50:17.541: E/AndroidRuntime(2152): Caused by: java.lang.NullPointerException
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1117)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.BackStackRecord.run(BackStackRecord.java:592)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.Activity.performStart(Activity.java:4474)
09-20 13:50:17.541: E/AndroidRuntime(2152):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1929)
09-20 13:50:17.541: E/AndroidRuntime(2152):     ... 11 more

在我的代码中删除片段的位置(注意:日志在崩溃之前输出“remove fragment:yes”,所以我认为removeFragments()实际上可以正常工作,而且可能是另外两种方法。

private void removeFragments() {
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.addOnBackStackChangedListener(this);

        boolean hasMessageListFragment = (mMessageListFragment != null);

        if (!hasMessageListFragment) {
            FragmentTransaction ft = fragmentManager.beginTransaction();
            mMessageListFragment = MessageListFragment.newInstance(mSearch,
                    false, (K9.isThreadedViewEnabled() && !mNoThreading));
            ft.remove(mMessageListFragment);
            ft.commit();

            Log.d("removed fragment?", "yes");
        }

        // Check if the fragment wasn't restarted and has a MessageReference in
        // the arguments. If
        // so, open the referenced message.
        if (!hasMessageListFragment && mMessageViewFragment == null
                && mMessageReference != null) {
            openMessage(mMessageReference);
        }
    }



private void removeMessageViewFragment() {
        if (mMessageViewFragment != null) {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.remove(mMessageViewFragment);
            mMessageViewFragment = null;
            ft.commit();

            showDefaultTitleView();
        }
    }

private void removeMessageListFragment() {
    if (mMessageViewFragment != null) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.remove(mMessageListFragment);
        mMessageListFragment = null;
        ft.commit();
    }
}

活动代码在此处:http://pastebin.com/VUzZeBJL

这是MessageList片段的代码:http://pastebin.com/fqVqLqb8

这是MessageView片段的代码(即使在Activity的onCreate期间永远不会打开):http://pastebin.com/fLWDXqyX

1 个答案:

答案 0 :(得分:1)

我认为这是你问题的根源:

if (!hasMessageListFragment) {
    FragmentTransaction ft = fragmentManager.beginTransaction();
    mMessageListFragment = MessageListFragment.newInstance(mSearch,
            false, (K9.isThreadedViewEnabled() && !mNoThreading));

    // Removing a Fragment which was never added
    ft.remove(mMessageListFragment);
    ft.commit();

    Log.d("removed fragment?", "yes");
}

您正在尝试删除从未添加到Fragment的{​​{1}}。为什么永远工作,我不知道,但这肯定不是FragmentManager的正确用法。