8

伙计们,

我通过 onCreate 顶部这样的代码片段捕获未处理的 Android 异常:

    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());
    }

我想为我在我的 android 应用程序中使用的大约两打 AsyncTasks 提出类似的东西,所以在 doInBackground 中发生的未处理的异常被捕获并记录下来。

问题是,因为 AsyncTask 采用任意类型的初始值设定项,我不确定如何声明一个超类,我的所有 AsyncTask 都从该超类继承,它设置了这个未处理的异常处理程序。

任何人都可以推荐一个好的设计模式来处理 AsyncTask 的 doInBackground 方法中未处理的异常,该方法不涉及为每个新的 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 来执行必要的日志记录/上传。

4

2 回答 2

3

我不会将其称为设计模式,而只是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);
}
于 2011-08-11T06:00:37.227 回答
0

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(),"");
    }
}
于 2011-08-11T05:59:55.990 回答