Android上的AsyncTask和错误处理

Bos*_*one 146 error-handling android handler android-asynctask

我使用转换我的代码HandlerAsyncTask.后者非常擅长它 - 在主UI线程中异步更新和处理结果.我不清楚的是,如果出现问题,如何处理异常AsyncTask#doInBackground.

我这样做的方法是有一个错误处理程序并向它发送消息.它工作正常,但它是"正确的"方法还是有更好的选择?

另外我理解如果我将错误处理程序定义为Activity字段,它应该在UI线程中执行.但是,有时(非常不可预测)我会得到一个异常,说触发的代码Handler#handleMessage是在错误的线程上执行的.我应该初始化错误处理程序Activity#onCreate吗?放置runOnUiThreadHandler#handleMessage似乎是多余的,但执行非常可靠.

Com*_*are 175

它工作正常,但它是"正确"的方法,还有更好的选择吗?

我抓住Throwable或者ExceptionAsyncTask实例中然后用它做一些事情onPostExecute(),所以我的错误处理可以选择在屏幕上显示一个对话框.

  • @Bruiser:https://github.com/commonsguy/cw-lunchlist/tree/master/15-Internet/LunchList按照我描述的模式有一个`AsyncTask`. (18认同)
  • 辉煌!不再需要处理程序了 (8认同)
  • 这是我应该抓住Throwable还是Exception的方式?"将一个实例变量添加到您自己的AsyncTask子类中,该子类将保存后台处理的结果." 当您收到异常时,将异常(或其他一些错误字符串/代码)存储在此变量中.调用onPostExecute时,请查看此实例变量是否设置为某个错误.如果是这样,请显示错误消息."(来自用户"波士顿街道"http://groups.google.com/group/android-developers/browse_thread/thread/ffa3d9c589f8d753) (5认同)
  • 您好,CW,请您详细解释一下这样做的方式 - 也许还有一个简短的代码示例?非常感谢!! (2认同)

Cag*_*lan 137

创建一个AsyncResult对象(您也可以在其他项目中使用)

public class AsyncTaskResult<T> {
    private T result;
    private Exception error;

    public T getResult() {
        return result;
    }

    public Exception getError() {
        return error;
    }

    public AsyncTaskResult(T result) {
        super();
        this.result = result;
    }

    public AsyncTaskResult(Exception error) {
        super();
        this.error = error;
    }
}
Run Code Online (Sandbox Code Playgroud)

从AsyncTask doInBackground方法返回此对象,并在postExecute中检查它.(您可以将此类用作其他异步任务的基类)

下面是一个从Web服务器获取JSON响应的任务的模型.

AsyncTask<Object,String,AsyncTaskResult<JSONObject>> jsonLoader = new AsyncTask<Object, String, AsyncTaskResult<JSONObject>>() {

        @Override
        protected AsyncTaskResult<JSONObject> doInBackground(
                Object... params) {
            try {
                // get your JSONObject from the server
                return new AsyncTaskResult<JSONObject>(your json object);
            } catch ( Exception anyError) {
                return new AsyncTaskResult<JSONObject>(anyError);
            }
        }

        protected void onPostExecute(AsyncTaskResult<JSONObject> result) {
            if ( result.getError() != null ) {
                // error handling here
            }  else if ( isCancelled()) {
                // cancel handling here
            } else {

                JSONObject realResult = result.getResult();
                // result handling here
            }
        };

    }
Run Code Online (Sandbox Code Playgroud)

  • "无害" - 冗余代码总是对可读性和维护有害.把它拿出来!:) (7认同)
  • 好主意,只有一个问题:当类没有扩展任何东西时,为什么在`AsyncTaskResult`中调用`super()`? (4认同)
  • 真的很喜欢这个解决方案...来考虑一下 - C#们在C#对应的BackgroundTask本机实现中使用了完全相同的方法...... (2认同)

sul*_*lai 10

当我觉得需要AsyncTask正确处理Exceptions 时,我将它用作超类:

public abstract class ExceptionAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {

    private Exception exception=null;
    private Params[] params;

    @Override
    final protected Result doInBackground(Params... params) {
        try {
            this.params = params; 
            return doInBackground();
        }
        catch (Exception e) {
            exception = e;
            return null;
        }
    }

    abstract protected Result doInBackground() throws Exception;

    @Override
    final protected void onPostExecute(Result result) {
        super.onPostExecute(result);
        onPostExecute(exception, result);
    }

    abstract protected void onPostExecute(Exception exception, Result result);

    public Params[] getParams() {
        return params;
    }

}
Run Code Online (Sandbox Code Playgroud)

正常情况下,您doInBackground在子类中重写以执行后台工作,愉快地在需要时抛出异常.然后你被迫实现onPostExecute(因为它是抽象的),这会轻轻地提醒你处理所有类型的Exception,它们作为参数传递.在大多数情况下,异常会导致某种类型的ui输出,因此这onPostExecute是一个完美的地方.


lud*_*igm 5

如果你想使用RoboGuice框架为你带来其他好处,你可以尝试RoboAsyncTask,它有一个额外的Callback onException().工作真的很好,我用它. http://code.google.com/p/roboguice/wiki/RoboAsyncTask