【发布时间】:2023-03-18 22:21:01
【问题描述】:
最近我正在调查一个 Android 应用程序的崩溃。我找到了原因并修复了它,但从那时起我一直想知道如何处理它(“处理”是指捕获它以避免“未处理”异常。)
当我启动一个新的 Activity 时发生了崩溃。但这不是在执行我的源代码中对我可见的任何代码时。相反,它在我退出代码中的最后一个事件处理程序后但在视图显示之前崩溃了。
我的 Activity 中有几个事件处理程序,例如 onCreate()、onPause() 和 onAttachedToWindow()。在后者中,我做了一个 . . .
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
该程序最初是针对 API 8 构建的,但是当我切换到 API 18 时,它就开始崩溃了。基于另一个 SO 问题,我注释掉了该行,问题就消失了。
当它崩溃时,显示器显示 . . .
W/dalvikvm: threadid=1: 线程以未捕获的异常退出 (group=0x4136a960) E/AndroidRuntime: 致命异常: main java.lang.IllegalArgumentException:添加窗口后无法更改窗口类型。 在 android.os.Parcel.readException(Parcel.java:1429) 在 android.os.Parcel.readException(Parcel.java:1379) 在 android.view.IWindowSession$Stub$Proxy.relayout(IWindowSession.java:860) 在 android.view.ViewRootImpl.relayoutWindow(ViewRootImpl.java:4755) 在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1661) 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1236) 在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5160) 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:791) 在 android.view.Choreographer.doCallbacks(Choreographer.java:591) 在 android.view.Choreographer.doFrame(Choreographer.java:561) 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777) 在 android.os.Handler.handleCallback(Handler.java:725) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:176) 在 android.app.ActivityThread.main(ActivityThread.java:5365) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 在 dalvik.system.NativeStart.main(Native Method) I/Process: 发送信号。 PID: 23536 SIG: 9 断开连接 目标虚拟机,地址:'localhost:8600',传输:'socket'
我的 startActvity() 已经被包裹在一个 try/catch 中,但它没有在那里着陆。 . .
Intent svc = new Intent(ctx, RegisterActivity.class);
svc.putExtra("Projectors2Register", params);
try {
ctx.startActivity(svc);
}
catch (Exception e) {
Log.e("ShowButtons(normal)Reg", "Exception" + e);
}
那么我可以在哪里放置一个处理程序来在将来捕获这些类型的崩溃?
...注意,我所说的“这些”崩溃并不是特指“TYPE_KEYGUARD”;我的意思是当系统设置或显示之前在我的代码内部调用的屏幕/视图时发生在我的代码之外的崩溃。
换句话说,我不希望用户在不通过我编写的错误处理程序的情况下得到“不幸的是你的应用程序已停止”错误。我希望能够记录每次崩溃的详细信息、用户在做什么,并优雅地关闭连接并告诉用户发生了什么。
【问题讨论】:
-
setType行是否包含在它自己的 try-catch 块中? -
这是一个可能不应该被“处理”的异常,因为它指向一个编程错误。以某种方式隐藏它只会使修复它的诊断复杂化。
-
_setType 行是否包含在它自己的 try-catch 块中? _ 是的。正如我在 OP 中所说,在离开我的代码后会发生崩溃 - 所有事件处理程序都正常退出,而实际的崩溃会在 Android 尝试建立 View 时发生。
-
@Henry 这是一个可能不应该“处理”的异常,因为它指向一个编程错误。以某种方式隐藏它只会使修复它的诊断复杂化。我不同意。处理它允许程序员记录有关崩溃和用户正在做什么的信息,以帮助诊断。否则用户只会收到“不幸的是,您的应用已停止”,那么您如何诊断呢?
-
@user316117 用户根本不应该得到它。不应该发布带有此类错误的代码。 “处理”异常不仅仅是记录它:您必须在运行时恢复,以防出现真正的运行时错误。或修复导致它的编码问题,如本例所示。
标签: android exception-handling