为啥完成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
为啥 FileOutputStream 会抛出 FileNotFoundException?
为啥“prepareCall”会抛出 NumberFormatException?