I'm adding Crashlytics into an app and I ran a couple tests. When I throw an exception within an async task the report didn't appear in the console. Is this a known issue or should it be coming through?
AsyncTask.execute(new Runnable()) {
@Override public void run() {
throw new RuntimeException("THIS IS A TEST");
}
}
I know that Crashlytics is set up correctly because an exception thrown from the same function but outside the AsyncTask wrapper shows up just fine. Can anyone else share their experience with crashes that occur asynchronously?
UPDATE
I ran more tests and I found that part of my issue was that I had a handler for uncaught exceptions. I had this in place so testers would get a dialog box and they could just tap OK to get a logcat attached to an email. (Thanks to need-to-handle-uncaught-exception-and-send-log-file) I tried a number of things and I in my case I just need to pick one or the other, the uncaught exception handler or the crashlytics. It works for me this way since I only really want the crashlytics in place for the production+release variant.
I tried including Crashlytics.logException(e)
in the body of the exception handler but that didn't work. Possibly because the function calls System.exit(1)
right after. Anyway... this is what I have now that does the job.
To use a custom application class, update the manifest
<application
android:name=".util.App"
In the App class I either set up the uncaught exception handler or the crashlytics.
public class App extends Application {
public void onCreate() {
super.onCreate();
Constants.IS_DEV = BuildConfig.FLAVOR.equals("dev");
if (Constants.IS_DEV || BuildConfig.DEBUG) {
setupUncaughtExceptionHandler();
} else {
Fabric.with(this, new Crashlytics());
}
[SNIP]
}
private void setupUncaughtExceptionHandler() {
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
handleUncaughtException(thread, e);
}
});
}
public void handleUncaughtException(Thread thread, Throwable e) {
// Crashlytics.logException(e); did not work here
// create intent to launch new instance and show 'send_log' dialog
Intent intent = new Intent();
intent.setAction(BuildConfig.APPLICATION_ID + ".SEND_LOG");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
System.exit(1); // kill this instance
}
[SNIP]
}
My tests were just functions I grabbed in the settings page. They're just text items with onClick method set to 'onClick' (how original :)
public class SettingsActivity extends DataSourcedActivity {
[SNIP]
public void onClick(View view) {
if (view == findViewById(R.id.txtSettingsRemove)) {
launchRemoveItemsPage();
} else if (view == findViewById(R.id.txtSettingsRestorePurch)) {
launchRestorePurchases();
} else if (view == findViewById(R.id.txtContactSupport)) {
launchContactSupport();
} else if (view == findViewById(R.id.txtGetUpdates)) {
launchGetUpdates();
} else {
throw new DevException(Constants.UNKNOWN_SETTINGS_OPTION);
}
}
private void launchRemoveCollectionsPage() {
AsyncTask.execute(new Runnable()) {
@Override
public void run() {
throw new RuntimeException("THIS IS AN ASYNCHRONOUS TEST");
}
}
[SNIPPED ORIGINAL CONTENTS OF FUNCTION]
}
private void launchRestorePurchases() {
throw new RuntimeException("THIS IS A TEST");
[SNIPPED ORIGINAL CONTENTS OF FUNCTION]
}
[SNIP]
}
When I tried to use both the Crashlytics and the uncaughtException handler I got different results depending on which I set up first. If I setup Crashlytics first and then my uncaughtExceptionHandler then it appeared that mine overrode Crashlytics, no crash report made it to the console. If I setup my uncaughtExceptionHandler first then I do get the crash report on the console.
So I'm leaving this here just in case it might be helpful to others who run into this.
Mike