Android Global Error Handling and Reporting Activity

Androider picture Androider · Apr 21, 2011 · Viewed 9.8k times · Source

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.

Answer

Kevin Gaudin picture Kevin Gaudin · Apr 21, 2011

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.