当 OnClickListener.onClick 中出现 NullPointerException 时 Android 冻结(其他任务无法启动)
Posted
技术标签:
【中文标题】当 OnClickListener.onClick 中出现 NullPointerException 时 Android 冻结(其他任务无法启动)【英文标题】:Android freezes when there is a NullPointerException in OnClickListener.onClick (other tasks cannot start) 【发布时间】:2013-03-30 10:58:26 【问题描述】:我有一个简单的设置:
CrashHandler
- 实现Thread.UncaughtExceptionHandler
的类;
CrashActivity
- 可以发送用户报告的活动;
MainActivity
- 用户应该与之交互的主应用程序。
当MainActivity
或其任何线程中存在未捕获的异常时,CrashHandler
会拦截它并创建一个通知以启动CrashActivity
:
Intent it = new Intent("CrashReporter" + SystemClock.currentThreadTimeMillis());
it.setClass(context, CrashActivity.class);
it.setFlags(it.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
与此同时,android 显示“应用程序崩溃”消息,用户单击确定,应用程序关闭,然后用户可能单击notification
。如果单击notification
,CrashActivity
将启动并显示。
这段代码已经在许多不同的情况下工作了很长时间(主线程崩溃,handler
崩溃,后台thread
崩溃......)。但是,我最近发现,如果在附加到MainActivity
中的button
的侦听器中的OnClickListener.onClick
方法中抛出异常,则它不起作用。情况如下:
-
我执行的代码故意抛出
NullPointerException
;
CrashHandler
拦截它并创建一个notification
(如图所示);
Android 不显示任何消息(例如,没有应该可见的“应用程序崩溃”);
MainActivity
被冻结;
如果用户单击通知以启动CrashActivity
,则会显示黑屏并冻结所有内容(未显示所需的活动)。
Logcat
显示启动超时,甚至在OnCreate
或我的任何代码之前:
I/ActivityManager(11826): START u0 act=CrashHandler1196 flg=0x14000000 cmp=mycompany.myapp/.CrashActivity bnds=[0,102][720,230] (has extras) from pid -1
W/KeyguardViewMediator(11826): verifyUnlock called when not externally disabled
W/ActivityManager(11826): Activity pause timeout for ActivityRecord41f4d988 u0 mycompany.myapp/.MainActivity
W/ActivityManager(11826): Launch timeout has expired, giving up wake lock!
W/ActivityManager(11826): Activity idle timeout for ActivityRecord4225eeb8 u0 mycompany.myapp/.CrashActivity
如果在单击notification
之前我从ADB
中终止了该应用程序,那么notification
可以完美运行。
如果在点击 notification
之前我在冻结的应用程序上做了一些点击和手势,几秒钟后我收到一条关于 ANR
的消息:
E/ActivityManager(11826): ANR in mycompany.myapp (mycompany.myapp/.MainActivity)
E/ActivityManager(11826): Reason: keyDispatchingTimedOut
E/ActivityManager(11826): Load: 0.63 / 0.57 / 0.49
如果我点击“是,杀了它”,然后点击notification
,就完美了。
CrashHandler
中添加System.exit
(-1),应用程序会立即退出并且通知工作正常(不幸的是,我无法在生产中使用此解决方案)。
我有两个问题:
-
为什么
OnClickListener.onClick
中的NullPointer exception
不会导致应用崩溃,而是将其与操作系统一起冻结并阻止其他活动启动?
一般要怎么做才能避免它,或者至少,如何使CrashActivity
在这些条件下启动?
【问题讨论】:
我认为您应该发布一些来自 onClick 的代码,以便我们理解。 【参考方案1】:没有看到你的代码,你应该调试你的 CrashHandler 类。 JVM 将忽略此中的所有异常
void uncaughtException(Thread t, Throwable e)
“Java 虚拟机将忽略此方法引发的任何异常。” (JavaDoc)。
我说这不是答案,但如果此方法引发异常,它可能是答案。
【讨论】:
【参考方案2】:为什么你不能杀死你自己的应用程序进程 https://developer.android.com/reference/android/os/Process.html#sendSignal(int, int)?
【讨论】:
以上是关于当 OnClickListener.onClick 中出现 NullPointerException 时 Android 冻结(其他任务无法启动)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 DialogInterface.OnClickListener.onClick() 中获取 Activity 上下文?