Android 全局错误处理和报告活动
我有什么方法可以注册一个全局错误处理程序来防止应用程序崩溃?此处描述了崩溃报告:如何获取崩溃-来自我的 Android 应用程序的数据?。我的一个想法是扩展这些解决方案以纳入应用程序上下文,以便可以重定向到特定的报告活动?但不确定一旦发生崩溃报告此时应用程序上下文是否有效?
但是,当发生崩溃时,如何将用户重定向到全局错误消息活动呢?是否有一些高级方法来注册错误处理程序来捕获所有错误并防止崩溃?有没有办法注册这样的处理程序,以便它可以防止崩溃或在崩溃中幸存下来,然后将用户重定向到特定的活动,该活动将显示相关的错误消息?
这是我对错误处理程序的修改:
1) 只需将 applicationContext
作为 ctx 传递到构造函数中
2) 添加 reportError(stackTrace)
方法将控制权转移到错误消息页面
private void reportError(String stackTrace){
Intent i = new Intent(ctx, DisplayErrorActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setAction("DISPLAY_ERROR_ACTIVITY");
Bundle b = new Bundle();
b.putString("STACKTRACE", stackTrace);
i.putExtras(b);
try{
Log.d("MyErrorHandler","reportError ctx="+ctx);
ctx.startActivity(i);
} catch (Exception e) {
Exception ex = e;
e.printStackTrace();
}
}
并调用 reportError
下面:
public void uncaughtException(Thread t, Throwable e) {
Log.d("MyUncoughtExceptionHandler", "uncoughtException ctx="+ctx);
String timestamp=getDateTime();
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
String filename = timestamp + ".stacktrace";
Log.d("MyexceptionHanlder","UncoughtException: "+stacktrace);
if (localPath != null) {
writeToFile(stacktrace, filename);
}
if (url != null) {
sendToServer(stacktrace, filename);
}
reportError(stacktrace);
// defaultUEH.uncaughtException(t, e);
}
如果我留下注释 defaultUEH
它会显示通常的崩溃对话框。没有它 - 空白屏幕。日志表明 ErrorMessageActivity
随进程一起被强制关闭。
为了测试,我只是在向线程注册错误处理程序后立即将除以零放入主活动的创建方法中。如果我有一个 try-catch 块,它就不会崩溃,但全局错误处理程序似乎并不能防止崩溃。检查了 ctx,它在调试器中似乎有效。
I there any way to register a global error handler that will prevent application from crashing? Crashing reporting is described here: How do I obtain crash-data from my Android application?. One thought I had was to extend these solutions to take in the application context so a redirect to a particular reporting activity could be made? But not sure if the application context is valid at this point once there is a crash to report?
But how can you redirect user to a global error message Activity when there is a crash? Is there some high level way to register an error handler that will catch all errors and prevent a crash? Is there a way to register such a handler so that it prevents or survives a crash and then redirects the user to a particular activity which will show the error message in question?
Here is my modification to error handler:
1) Just pass applicationContext
into constructor as ctx
2) add reportError(stackTrace)
method to transfer control to error message page
private void reportError(String stackTrace){
Intent i = new Intent(ctx, DisplayErrorActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setAction("DISPLAY_ERROR_ACTIVITY");
Bundle b = new Bundle();
b.putString("STACKTRACE", stackTrace);
i.putExtras(b);
try{
Log.d("MyErrorHandler","reportError ctx="+ctx);
ctx.startActivity(i);
} catch (Exception e) {
Exception ex = e;
e.printStackTrace();
}
}
And call reportError
below:
public void uncaughtException(Thread t, Throwable e) {
Log.d("MyUncoughtExceptionHandler", "uncoughtException ctx="+ctx);
String timestamp=getDateTime();
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
String filename = timestamp + ".stacktrace";
Log.d("MyexceptionHanlder","UncoughtException: "+stacktrace);
if (localPath != null) {
writeToFile(stacktrace, filename);
}
if (url != null) {
sendToServer(stacktrace, filename);
}
reportError(stacktrace);
// defaultUEH.uncaughtException(t, e);
}
If I leave commented defaultUEH
it shows usual crash dialog. Without it - blank screen. Log indicates that ErrorMessageActivity
is force closed along with the process.
To test I just put divide by zero in create method of main activity right after registering the error handler with the thread. If I had a try-catch
block over this it would not crash, but the global error handler does not seem to prevent crash. Checked ctx
and it seems valid in a debugger.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在实施 ACRA 时,我在收到未捕获的异常后始终无法启动新的 Activity。看起来整个过程被系统切换到了特殊状态,阻止他允许任何新资源。
目前我找到的唯一选择是发送状态栏通知,该通知在应用程序重新启动后由系统保留。然后,当用户选择通知时,该通知会触发对话活动的意图。
Alexey Yakovlev 更详细地研究了这个问题,并得出结论:当崩溃发生在非 UI 线程的线程上时,可能有机会触发新的活动。尽管我们没有找到足够简单的解决方法来在所有情况下直接启动活动。
我通过自己终止进程而不调用原始的默认未捕获异常处理程序来摆脱默认的强制关闭对话框。
When implementing ACRA, I have never been able to start a new Activity after receiving an uncaught exception. It looks like the whole process is switched by the system to a special state preventing him from allowing any new resource.
The only option I have found for the moment is to send a status bar notification which is kept by the system after the application being restarted. The notification then triggers an intent for a dialog activity when the user selects it.
Alexey Yakovlev studied in much more details this issue and came to the conclusion that there could be a chance of triggering a new activity when the crash occurs on a thread which is not the UI thread. Though we did not find a simple enough workaround to start directly an activity in all cases.
I got rid of the default force close dialog by killing the process myself without invoking the orginial default uncaught exception handler.
你可以
setUncaughtExceptionHandler
为您的线程。you can
setUncaughtExceptionHandler
for your thread.