为什么在结束Activity时会抛出NPE异常?

4

我有一个错误让我疯狂了好几天。不幸的是,由于两个原因,我不能向您展示代码,一是我的老板不会欣赏,二是代码库太大了无法共享。每当Activity即将关闭时,就会出现错误。无论是因为我调用finish()还是因为操作系统销毁它。

问题是:在FragmentManagerImpl中,什么原因(或可能)导致execPendingActions()在第1196行抛出NPE。

以下是堆栈跟踪:

FragmentManagerImpl.execPendingActions() line: 1196 
FragmentManagerImpl$1.run() line: 375   
Handler.handleCallback(Message) line: 587   
Handler.dispatchMessage(Message) line: 92   
Looper.loop() line: 126 
ActivityThread.main(String[]) line: 3997    
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
Method.invoke(Object, Object...) line: 491  
ZygoteInit$MethodAndArgsCaller.run() line: 841  
ZygoteInit.main(String[]) line: 599 
NativeStart.main(String[]) line: not available [native method]  

我认为你真的需要发布一些代码... - PJL
我不知道。只是把问题想象成“什么原因会导致在FragmentManagerImpl的第1196行抛出NPE”。 - Gallal
只有两个活动 - 主要和首选项,8个片段,以及大约25个类加上一个服务。主要部分大约有600行代码,退出时是唯一会崩溃的部分。 - Gallal
1
@Gallal 你可以尝试使用兼容库并进行调试。或者,尝试在简化的示例应用程序中重现问题。 - PJL
@Gallal,请您也帮我看一下吧?我遇到了类似的问题。请查看http://stackoverflow.com/q/13266795/1516775。谢谢! - MGDroid
显示剩余3条评论
4个回答

2

您可能遇到了Fragment Manager的一个错误,即在被销毁之前它没有清除其待处理事务列表。如果您在状态保存后提交事务,使用FragmentTransaction.commitAllowingStateLoss(),就会发生这种情况。您可以通过以下代码解决此问题:

@Override void onDestroy() {
    getFragmentManager().executePendingTransactions();
    super.onDestroy();
}

1
不幸的是,我已经尝试过这个了,但它不起作用。根据文档,它返回false,这意味着没有待处理的交易。 - Gallal

2

当谈到完成活动时:您是否试图从视图中finish()活动?是否正确发送了MyClass.this.finish()

在我的看来,操作系统强制关闭它是因为空指针异常。片段中有些问题。其中一些内容为空。你能至少粘贴出它崩溃的那一行吗?


该行代码是在Activity中的'finish();'。 - Gallal
片段在应用程序的20多个位置进行操作,因此很难向您展示我如何处理可能导致此问题的片段。 - Gallal
检查您如何完成活动,检查您是否从片段中完成活动,检查您是否正确填充。 - Nikola Despotoski
尝试启动片段的活动以获取结果,然后尝试使用结果完成它们...然后finish()整个活动...这只是一个想法,可能可以避免这种情况。 - Nikola Despotoski
我的意思是刪除其餘的片段,然後完成。 - Nikola Despotoski
使用 getActivity() 方法获取与该片段相关联的活动。 - Nikola Despotoski

1

你可以尝试使用compat库并进行调试。

或者,尝试在一个简化的样例应用程序中复现问题。


这个答案很有帮助。它让我发现在一个片段的onDestroy()方法中,我正在对一个空引用调用一个方法。不幸的是,堆栈跟踪并没有表明清楚。感谢@PJL! - Gallal

0

NullPointerException的原因是Activity的Handler未从FragmentManager中unset,因此防止崩溃的“解决方案”如下:

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

        } 
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接