AsyncTask

AsyncTask类原型

public abstract class AsyncTask<Params, Progress, Result>
  • 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<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
        Params... params) {
    ...
    onPreExecute();
    exec.execute(mFuture);
    return this;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android开发者:你真的会用AsyncTask吗? 导读.1 在Android应用开发中,我们需要时刻注意保证...
    cxm11阅读 2,729评论 0 29
  • Android Handler机制系列文章整体内容如下: Android Handler机制1之ThreadAnd...
    隔壁老李头阅读 3,255评论 1 15
  • AsyncTask 1.简介 AsyncTask允许你执行后台耗时操作,并将结果发布到UI线程。整个实现过程不需要...
    chewbee阅读 1,401评论 0 1
  • 在Android中我们可以通过Thread+Handler实现多线程通信,一种经典的使用场景是:在新线程中进行耗时...
    吕侯爷阅读 2,066评论 2 23
  • 最近一直琢磨着写一个个人主页,一番研究之后决定使用Jekyll在Github Page上搭建主页。用了一天半的时间...
    _敏讷阅读 391评论 0 1