为啥完成Activity会抛出NPE?

Posted

技术标签:

【中文标题】为啥完成Activity会抛出NPE?【英文标题】:Why is NPE thrown when finishing Activity?为什么完成Activity会抛出NPE? 【发布时间】:2011-10-10 02:39:43 【问题描述】:

我有一个错误让我疯狂了好几天。不幸的是,我无法向您展示代码有两个原因,我的老板不会欣赏它,并且代码库太大而无法分享。只要活动完成,就会发生错误。天气是因为我调用了 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]  

【问题讨论】:

我认为您确实需要发布一些代码... 我不能。只需将问题想象为“什么可能导致 NPE 在 FragmentManagerImpl 的第 1196 行被抛出” 是针对每一项活动还是仅针对这一项?你能至少描述一下代码在做什么吗? 只有两个活动 - Main 和 Preferences,8 个 Fragments,以及 25 个左右的类和一个服务。 Main 大约有 600 行,它是唯一在退出时崩溃的行。 @Gallal 您可以尝试使用兼容库并对其进行调试。或者尝试在精简的示例应用中重现。 【参考方案1】:

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

在我看来,操作系统强制它关闭了 NPE。碎片有问题。其中有些是空的。您至少可以粘贴崩溃的那一行吗?

【讨论】:

该行是'finish();'从 Activity 中。 片段在整个应用程序的 20 多个位置进行操作,因此我很难向您展示我如何处理可能导致此问题的片段。 检查你如何完成活动,检查你是否从片段完成活动,检查你是否正确充气。 尝试启动片段的活动以获得结果,并尝试用结果完成它们......然后完成()整个活动......只是一个想法,可能会避免这种情况。 我的意思是删除其余的片段,然后完成。【参考方案2】:

您可能在片段管理器中遇到了一个错误,它在被销毁之前没有清除其待处理事务列表。如果您在保存状态后使用 FragmentTransaction.commitAllowingStateLoss() 提交事务,则会发生这种情况。您也许可以在您的活动中使用此代码来解决它:

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

【讨论】:

不幸的是,我已经尝试过了,但它不起作用。它返回 false,根据文档,这意味着没有待执行的事务要执行。【参考方案3】:

您可以尝试使用兼容库并对其进行调试。

或者尝试在精简的示例应用中重现。

【讨论】:

这个答案有帮助。它导致发现在片段的一个 onDestroy() 中,我正在对空引用调用一个方法。不幸的是,堆栈跟踪并没有说清楚。谢谢@PJL!【参考方案4】:

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) 

         
 

【讨论】:

以上是关于为啥完成Activity会抛出NPE?的主要内容,如果未能解决你的问题,请参考以下文章

java 测试的HashMap和ConcurrentHashMap中是否可以存储密钥为空的数据,测试显示前者可以,后者是不可以的,会在看跌的时候校验密钥是否为空,如果为空则会抛出数Npe

为啥有时会抛出 FileNotFoundException

为啥 FileOutputStream 会抛出 FileNotFoundException?

为啥“prepareCall”会抛出 NumberFormatException?

为啥 BluetoothSetLocalServiceInfo 会抛出错误 1314?

为啥geoip会抛出异常?