Folks,
I catch unhandled Android exceptions via a code snippet like this, at the top of onCreate:
try {
File crashLogDirectory = new File(Environment.getExternalStorageDirectory().getCanonicalPath() + Constants.CrashLogDirectory);
crashLogDirectory.mkdirs();
Thread.setDefaultUncaughtExceptionHandler(new RemoteUploadExceptionHandler(
this, crashLogDirectory.getCanonicalPath()));
} catch (Exception e) {
if (MyActivity.WARN) Log.e(ScruffActivity.TAG, "Exception setting up exception handler! " + e.toString());
}
I'd like to come up with something similar for about two dozen AsyncTasks I use in my android application, so unhandled exceptions that occur in doInBackground are caught & logged.
Problem is, because AsyncTask takes arbitrary type initializers, I am not sure how to declare a superclass, from which all my AsyncTasks inherit, that sets up this unhandled exception handler.
Can anyone recommend a good design pattern for handling unhandled exceptions in the doInBackground method of AsyncTask that does not involve copy-and-paste of code like that above for every new AsyncTask definition?
Thanks!
UPDATE
Here is the design pattern I used, after looking more closely at the source of AsyncTask
import java.io.File;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
public abstract class LoggingAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
protected void setupUnhandledExceptionLogging(Context context) {
try {
File crashLogDirectory = new File(Environment.getExternalStorageDirectory().getCanonicalPath() + Constants.CrashLogDirectory);
crashLogDirectory.mkdirs();
Thread.setDefaultUncaughtExceptionHandler(new RemoteUploadExceptionHandler(
context, crashLogDirectory.getCanonicalPath()));
} catch (Exception e) {
if (MyActivity.WARN) Log.e(ScruffActivity.TAG, "Exception setting up exception handler! " + e.toString());
}
}
}
Then I define my tasks as follows:
private class MyTask extends LoggingAsyncTask<Void, Void, HashMap<String, Object>> {
protected HashMap<String, Object> doInBackground(Void... args) {
this.setupUnhandledExceptionLogging(MyActivity.this.mContext);
// do work
return myHashMap;
}
}
Obviously your task can take whatever params necessary with this pattern. It's up to you to define RemoteUploadExceptionHandler to do the necessary logging/uploading.
I wouldn't go as far as to call it a design pattern, but just wrap doInBackground()
and initialize and/or catch exceptions as necessary.
public abstract class AsyncTaskWrapper<Params, Progress, Result> extends
AsyncTask<Params, Progress, Result> {
protected Exception error;
protected Result doInBackground(Params... params) {
try {
init();
return doRealWork(params);
} catch (Exception e) {
error = e;
Log.e("TAG", e.getMessage(), e);
return null;
}
}
protected abstract void init();
protected abstract Result doRealWork(Params... params);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With