Шаблон проектирования для перехвата необработанных исключений в AsyncTask
Народ,
Я ловлю необработанные исключения 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 принимает инициализаторы произвольного типа, я не знаю, как объявить суперкласс, от которого наследуются все мои AsyncTask, который устанавливает это необработанный обработчик исключений.
Может ли кто-нибудь порекомендовать хороший шаблон проектирования для обработки необработанных исключений в методе 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 I trap для исключений и возвращает объект BoolString, шаблон no throws
//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(),""); } }