85

If my app crashes, it hangs for a couple of seconds before I'm told by Android that the app crashed and needs to close. So I was thinking of catching all exceptions in my app with a general:

try {
    // ... 
} catch(Exception e) { 
    // ...
} 

And make a new Activity that explains that the application crashed instantly (and also giving users an opportunity to send a mail with the error details), instead of having that delay thanks to Android. Are there better methods of accomplishing this or is this discouraged?

Update: I am using a Nexus 5 with ART enabled and I am not noticing the delay I used to experience with apps crashing (the "hanging" I was talking about originally). I think since everything is native code now, the crash happens instantly along with getting all the crash information. Perhaps the Nexus 5 is just quick :) regardless, this may not be a worry in future releases of Android (given that ART is going to be the default runtime in Android L).

ldam
  • 4,412
  • 6
  • 45
  • 76
  • 1
    please [check link](https://developers.google.com/analytics/devguides/collection/android/v2/exceptions) – CRUSADER May 15 '13 at 10:01
  • when crash happens your activity is destroyed so there is no way to handle the crash yourself. – Raghunandan May 15 '13 at 10:07
  • @Raghunandan yes but if the crash happens because of an unhandled exception you can use a general catch all exception handler and prevent it from completely crashing. – ldam May 15 '13 at 10:17
  • @LoganDam Ever figure anything out? – theblang Nov 12 '13 at 14:33
  • @mattblang I actually haven't touched my android stuff in quite a while now, work has been crazy. Might get back into the android world again soon though. CRUSADER's option looks like the way to go from the reading I've done. – ldam Nov 13 '13 at 12:10

3 Answers3

107

Here, check for the link for reference.

In here you create a class say ExceptionHandler that implements java.lang.Thread.UncaughtExceptionHandler..

Inside this class you will do your life saving stuff like creating stacktrace and gettin ready to upload error report etc....

Now comes the important part i.e. How to catch that exception. Though it is very simple. Copy following line of code in your each Activity just after the call of super method in your overriden onCreate method.

Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));

Your Activity may look something like this…

public class ForceClose extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));

        setContentView(R.layout.main);
    }
}

And this is a sample ExceptionHandler class:

public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
  private static final String TAG = "ExceptionHandler";

  @Override
  public void uncaughtException(@NonNull Thread thread, @NonNull Throwable exception) {
    Log.e(TAG, "uncaughtException: " + "\n" + getErrorReport(exception));
    Log.i(TAG, getDeviceInfo());
    Log.i(TAG, getFirmwareInfo());

    stopTheApp();
  }

  private String getErrorReport(@NonNull Throwable exception) {
    ApplicationErrorReport.CrashInfo crashInfo = new ApplicationErrorReport.CrashInfo(exception);

    return "\nCAUSE OF ERROR\n" +
      crashInfo.stackTrace;
  }

  private String getDeviceInfo() {
    return
      "\nDEVICE INFORMATION\n" +
        "Brand: " +
        Build.BRAND +
        "\n" +
        "Device: " +
        Build.DEVICE +
        "\n" +
        "Model: " +
        Build.MODEL +
        "\n" +
        "Id: " +
        Build.ID +
        "\n" +
        "Product: " +
        Build.PRODUCT +
        "\n";
  }

  private String getFirmwareInfo() {
    return "\nFIRMWARE\n" +
      "SDK: " +
      Build.VERSION.SDK_INT +
      "\n" +
      "Release: " +
      Build.VERSION.RELEASE +
      "\n" +
      "Incremental: " +
      Build.VERSION.INCREMENTAL +
      "\n";
  }

  private void stopTheApp() {
    android.os.Process.killProcess(android.os.Process.myPid());
  }
}
CRUSADER
  • 5,486
  • 3
  • 28
  • 64
  • Your example activity doesn't implement `UncaughtExceptionHandler` :) thanks for the answer, I'll try it when I get home from work. – ldam May 15 '13 at 10:43
  • Also, should `Thread.setDefaultUncaughtExceptionHandler()` not be put in your main/first activity so it handles all exceptions within the application? – ldam May 15 '13 at 10:46
  • I said, to create a class say ExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler.... And then in your normal activities add above mentioned code line... Please refer link mentioned above to get broader idea.. – CRUSADER May 15 '13 at 10:47
  • @CRUSADER Thankyou so much that link which you have mentioned as reference link is working perfectly fine. – Ahmad Arslan Feb 17 '14 at 09:50
  • 8
    Or just add that line once to a BaseActivity and subclass this Activity throughout your app. – W.K.S Apr 10 '14 at 07:43
  • Has anyone actually got this to work well before? I find that the environment seems unstable during the exception handler, and it's hard to prevent the app/code from crashing or freezing. – Sam Nov 06 '14 at 07:40
10

You could just use a generic alert dialog to quickly display error messages. For example...

//******************************************
//some generic method
//******************************************
private void doStuff()
{       
    try
    {
        //do some stuff here
    }
    catch(Exception e)
    {
        messageBox("doStuff", e.getMessage());
    }
}


//*********************************************************
//generic dialog, takes in the method name and error message
//*********************************************************
private void messageBox(String method, String message)
{
    Log.d("EXCEPTION: " + method,  message);

    AlertDialog.Builder messageBox = new AlertDialog.Builder(this);
    messageBox.setTitle(method);
    messageBox.setMessage(message);
    messageBox.setCancelable(false);
    messageBox.setNeutralButton("OK", null);
    messageBox.show();
}

You could also add other error handling options into this method, such as print stacktrace

Louis Evans
  • 671
  • 2
  • 8
  • 18
4

i found the "wtf" (what a terrible failure) method in the Log class. From the description:

Depending on system configuration, a report may be added to the DropBoxManager and/or the process may be terminated immediately with an error dialog.

http://developer.android.com/reference/android/util/Log.html

mightyWOZ
  • 7,946
  • 3
  • 29
  • 46
sunyata
  • 1,843
  • 5
  • 27
  • 41