Pich Blog

关注移动开发,大数据,云计算,软件架构!

2.详解AsyncTask

概述

为了简化在子线程更新UI,系统提供了AsyncTask,但是他经过多次修改,导致在不同的API版本有不同的表现,尤其是在多任务并发。

是一种轻量级的异步人物类,他可以在线程池中执行任务,然后把任务进度和结果传递给主线程并更新UI。但他不适合进行特别耗时的任务,如果是建议使用线程池。

实现原理

内部封装了Thread,Handler。

参数

是一个抽象泛型类,提供了三个泛型:

​ Params:表示参数类型

​ Progress:执行进度类型

​ Result:返回结果类型

如果不需要传递,可以使用Void来代替。

提供的方法

提供了4个核心的方法:

onPreExecute()

在主线程执行,在执行任务前,此方法会被调用,一般用于准备工作,比如:显示开始对话框。

doInBackground(Params… params)

在线程池中执行,用户执行耗时任务,params表示传入的可变参数,在这里可以通过publishProgress方法来发布任务,该方法会调用onProgressUpdate方法。此方法返回的结构将传递到onPostExecute方法。

onProgressUpdate(Progress… values)

当调用publishProgress来发布任务进度是,该方法会被调用,在主线程执行。

onPostExecute(Result result)

异步任务执行完后,调用该方法,result是doInBackground返回的值。

onCancelled

在主线程执行,当异步任务呗取消,onCancelled被调用,但不会调用onPostExecute了

下载文件实例

然后这样使用这个类

如果不需要传递参数,需要这样申明AsyncTask。

然后这样传递null,才能调用。

AsyncTask限制

  1. 必须在主线程加载,也就说访问Asnyc必须在主线程,当前这个过程在4.1及以上中已经自定完成了,在5.0的源码中可以在ActivityThread的main方法中查看到他调用了AsyncTask的init方法,这也就买足了在主线程中进行加载这个条件了,为什么要满足了后面再分析。
  2. 创建对象也必须要在主线程中
  3. execute方法需要在UI线程中调用
  4. 不要在线程中调用onPreExecute这样的方法
  5. 一个AsyncTask只能执行一次
  6. 在1.6前,是串行执行任务的,1.6后采用线程池处理并发任务,3.0开始为了避免并发错误,他采用了一个线程来串行执行任务,但是在3.0开始我们任然可以通过调用executeOnExecutor方法来并发执行任务。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注