AsyncTask

AsyncTask类原型

public abstract class AsyncTask
  • Params:传递给AsyncTask的类型,作为doInBackground的参数类型
  • Progress:作为onProgressUpdate和publishProgress的参数类型
  • Result:由doInBackground返回,作为onPostExecute的参数类型

使用规则

  • 该类实例必须在UI线程中创建
  • execute方法必须在UI线程中调用
  • 一个任务实例只能执行一次

执行流程

  1. onPreExecute:在UI线程中执行,一般用于任务执行前初始化UI,如显示进度条对话框等
  2. doInBackground:在后台执行,期间可以调用publishProgress来更新进度条等内容
  3. onProgressUpdate:当publishProgress调用时在UI线程中执行,可更新进度条或显示文本等信息
  4. onPostExecute:在UI线程中执行,可以利用返回的结果更新UI,或者关闭进度条对话框等。
  5. onCanceled: 该方法运行在UI线程中,可以在方法中关闭进度条对话框等。

任务的取消

可以调用cancel取消任务,之后isCancelled会返回true。
取消任务后,doInBackground返回后,onPostExecute不再执行,而是onCancelled执行。
为了尽快取消任务,应该在doInBackground中调用isCancelled检查任务是否取消,以采取相应的行动。
在编写doInBackground方法时,应该不时地检查isCanceled的返回值,如果返回true,应该停止执行任务。
在onPostExecute中,应该调用isCanceled检测任务是否已经被取消。

另外,在调用execute执行后,应该注意它的取消操作。
例如在Activiy中,应该在Activity不可见时(onStop方法)取消操作。

当配置变化时

当配置变化时,如果进行了合适的取消,当Activity或Fragment重新启动时,会导致任务重新开始。

为了避免在配置变化时重新开始,可以把AsyncTask保存在Fragment中,当配置变化时,使用Fragment保证任务不会中断。

如果在执行任务时,同时显示了加载对话框,可以在配置变化时,dismiss对话框,当重新开始时,再显示对话框。

http://blog.csdn.net/lmj623565791/article/details/37936275

AsyncTask的适用场景和内存泄漏

AsyncTask应该用于短时间的任务。
如果作用于长时间的任务,且是内部类,那么保存了Activity的引用,会导致Activity不会被垃圾回收。可以通过静态类来解决。
同时,在更新UI时,会抛出异常。可以通过实现合适的取消机制来解决。

实现原理

为了实现可取消的操作,内部使用了FutureTask类。
同时,内部使用了线程池,默认情况下,只有一个任务在执行,其他任务会入队列等待执行。可以通过构造方法,传递自定义的Executor来并行执行。
-在Android 3.0之前,线程池可以并行执行5个任务,最大为128.
在Android 3.0及其之后,默认线程池为串行执行。
最后,为了能够更新UI,使用可扩展了Handler的静态内部类,它的Looper使用的是UI线程的。所以,可以发送消息给该Handler以更新进度条和UI等。

另外,根据源码可知,调用execute后,onPreExecute在调用线程中执行,所以AsyncTask必须在UI线程中执行。
因为AsyncTask中有些方法是根据调用线程来作为参数,所以AysncTask应该在UI线程中创建。

至于一个AsyncTask只能执行一次,我想可能是因为如果允许执行多次的话,如果线程池为多个线程并行执行,那么我们在扩展该类时,必须考虑线程同步的问题,这样就有点麻烦了。

public final AsyncTask execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask executeOnExecutor(Executor exec,
        Params... params) {
    ...
    onPreExecute();
    exec.execute(mFuture);
    return this;
}

你可能感兴趣的:(AsyncTask)