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.
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.