7C00.ME/houmu 2012-03-24

Android AsyncTask几个注意事项

CSDN上的这个系列文章《Android异步处理系列文章索引》对AsyncTask讲解的很清楚,特别是其中的几个例子特别好。最近在在做一个Android应用开发,都是用AsyncTask来完成后台任务,简单总结一下。

通常使用AsyncTask,是通过继承这个超类来完成的,如:

class BackgroundTask extends AsyncTask<Object,Object,Object> 
{
    @Override
    protected Object doInBackground(Object... params) 
    {
        return null;
    }
}

子类必须重载 doInBackground方法。“<>”里面的三个类型,依次代表执行参数类型、进度参数类型和结果参数类型。doInBackground的参数类型必须是执行参数类型,返回的类型必须和结果参数类型。这三个类型应该根据需要来定,其实用Object也可以,用的时候在做类型转换。启动一个AsyncTask,可以在这样做:

BackgroudTask bt = new BackgroundTask();
bt.execute("param");

使用AsyncTask的容易犯下的错误是在doInBackground方法里面直接对UI元素进行操作。如果需要和UI进行交互,可以配合使用publishProgress和onProgressUpdate。比如

@Override
protected Object doInbackground(Object... params) 
{
    ...
    publishProgress("完成了20%");
    ...
    publishProgress("完成了80%");
    ...
    return null;
}

protected void onProgressUpdate(Object... progress){
    ...
    textView1.setText((String)progress[0]);
    ...
}

这里onProgressUpdate是工作在UI线程的。

使用AsyncTask的另一个问题是关于cancel。实际上,单单调用AsyncTask对象的cancel方法,并不能停止doInBackground方法的继续执行。通常比较接受的方法是设置一个标志位,也就是在每次执行前检查一下某个变量的值(或者可以调用isCancelled方法判断),来决定继续执行还是停止。这种处理手段对于一些循环性的工作比较有用,但是对于一些循环性弱的工作可能并不怎么有效。这也算是AsyncTask的一个弱点。和Thread相比,AsyncTask还有一个弱点是效率的问题,这个可以在本文开头给出的链接中找到相关的信息。

AsyncTask还有一个问题和onPreExecute方法有关。这个方法是工作在UI线程的。虽然是叫onPreExecute,但是doInBackground方法(也就是实际上的execute),并不会等待onPreExecute方法做完全部操作才开始执行。所以,一般还是不要用这个方法,可以在调用AsyncTask对象的execute方法之前就把该完成的操作完成,以免引起某些错误。

AsyncTask还有一个方法是onPostExecute,这个方法也是工作在UI线程,它是在doInBackground方法执行结束,并返回结果后调用。这个方法里面可以调用UI线程的startActivity,这样可以实现完成大量后台操作后,自动跳转Activity的功能。这个方法里面也可以执行另一个AsyncTask的execute方法。