Шаблон проектирования для отлова необработанных исключений в AsyncTask
Folks,
Я перехватываю необработанные исключения Android через фрагмент кода, подобный этому, в верхней части 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());
}
Я хотел бы придумать что-то похожее для примерно двух десятков AsyncTasks, которые я использую в своем приложении для Android, поэтому необработанные исключения, возникающие в doInBackground, перехватываются и регистрируются.
Проблема в том, что AsyncTask принимает инициализаторы произвольного типа, я не уверен, как объявить суперкласс, от которого наследуются все мои AsyncTasks, который устанавливает этот обработчик необработанных исключений.
Кто-нибудь может порекомендовать хороший шаблон проектирования для обработки необработанных исключений в методе doInBackground AsyncTask, который не включает в себя копирование и вставку кода, подобного приведенному выше, для каждого нового определения AsyncTask?
Спасибо!
ОБНОВИТЬ
Вот шаблон дизайна, который я использовал после более внимательного изучения источника 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());
}
}
}
Затем я определяю свои задачи следующим образом:
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;
}
}
Очевидно, что ваша задача может принимать любые параметры, необходимые для этого шаблона. Вы должны определить RemoteUploadExceptionHandler для выполнения необходимой регистрации / загрузки.
2 ответа
Я не пошел бы так далеко, чтобы назвать это шаблоном дизайна, но просто обернуть doInBackground()
и инициализировать и / или перехватывать исключения по мере необходимости.
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);
}
esilver Я перехватываю исключения и возвращаю объект BoolString, шаблон не выбрасывает
//a utility class to signal success or failure, return an error message, and return a useful String value
//see Try Out in C#
public final class BoolString {
public final boolean success;
public final String err;
public final String value;
public BoolString(boolean success, String err, String value){
this.success= success;
this.err= err;
this.value= value;
}
}
ИСПОЛЬЗОВАНИЕ:
private class MyAsynch extends AsyncTask<String, Void, BoolString>{
protected BoolString doInBackground(String...strings) { // <== DO NOT TOUCH THE UI VIEW HERE
return model.tryMyMethod(...); // <== return value BoolString result is sent to onPostExecute
}
protected void onPostExecute(BoolString result){
progress.dismiss();
if (result.success){
... continue with result.value
}
else {
..log result.err
}
}
// NO THROWS VERSION Helper method
public BoolString tryMyMethod(...) {
try {
String value= MyMethod(...);
return new BoolString(true,"",value);
}
catch (Exception e){
return new BoolString(false,e.getMessage(),"");
}
}