AsyncTask 是android自己实现的一个异步类,个人觉得其本质是对Handler的一个封装,通过代码分析,可以看出其实AsyncTask最后还是通过handler来进行异步消息传递的。但是封装AsyncTask使得异步代码实现特别方便。
一、参数
AsyncTask有三个参数泛型函数,分别是Params,Progress,Result,这三个参数分别代表初始化参数,执行进度参数和返回结果参数;Params参数可以在execute方法中传入,然后再doInBackground方法中获取参数执行,Progress参数在publishProgress方法中传入,然后再onProgressUpdate获取然后进行处理,Result参数是doInBackGround方法的返回值,最后在onPostExecute方法获取返回。
二、拥有变量
AsyncTask拥有以下重要变量,
1、ThreadFactory线程工厂类,用来产生一个新线程并计数,支持多线程。
2、LinkedBlockingQueue充当多线程容器
3、ThreadPoolExecutor线程池管理类,该类定义的线程池是多线程的,核心线程数为CPU核数+1,最大线程数为2*CPU核数+1,经验证,这两个数据的线程池可以在多线程中得绝大多数情况保证负载和性能都有很好的结果,因此线程池推荐采用类中核数的定义方式:
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
4、SERIAL_EXECUTOR, 该类封装一个ArrayDeque,通过synchronized关键字给execute方法加锁,使得同时只有一个线程可以运行。每次运行时插入一个线程到Deque中,然后再从该ArrayDeque取出一个线程通过ThreadPoolExecutor执行,这个线程执行时只要Deque不为空,就会顺序取Deque队顶元素进行运算。
5、两个boolean变量,mCancelled和mTaskInvoked,分别代表该task是否取消和该task的核心线程是否调用。
6、一个handler,这个handler处理两个消息MESSAGE_POST_RESULT和MESSAGE_POST_PROGRESS,分别表示执行完成(或取消)和执行中更新进程。
三、状态
AsyncTask有三种状态,PENDING,RUNING,FINISHED,只有当状态是PENDING才能执行,后两种状态都会抛出异常,表明了一个AsyncTask只能执行一次,需要重新执行task,只能新建一个task。
四、初始化
初始化过程必须在UI线程中执行,因为不在UI线程执行那么其初始化的handler就无法捕获到UI线程,无法完成执行完毕的回调。
AsyncTask在构造函数会初始化一个workRunable其实就是一个callable,提供给futuretask管理,这个worker会设置mTaskInvoked状态为执行,然后调用doInBackground方法执行,最后返回要回调的handler。除此之外,AsyncTask初始化一个futuretask来管理worker,覆盖方法done(),这个方法表明在执行完成后检查该task的核心部分是否执行,如果没有执行也返回一个结果。
五、执行
可以通过调用get()方法获取handler,然后自己再进行回调。
普通的执行方法是通过execute(Params...)方法执行,这个方法执行默认调用SERIAL_EXECUTOR,即只允许同一时间只有一个线程运行。
想多线程可以通过executeOnExecutor方法执行,可以指定自己想要执行的Executor,通常只需指定为该类定义的ThreadPoolExecutor即可。
execute必须在UI线程中执行,主要是保证onPreExecute方法和本身的某些状态正确。
六、有用的方法。
onPreExecute(),该方法运行在由execute方法调用,执行在主线程中,
doInBackground(),该方法运行在一个子线程中,在worker的call()中调用
publishProgress(),该方法已经定义,不需要覆盖,只需自己在doInBackground()中调用即可。
onProgressUpdate(),由handler回调,运行在主线程中,获取当前运行进程并由自己完成回调。
onCancel(),task执行完成后由handler回调,当判断task已经取消,则调用该方法。
onPostExecute(),task执行完成后由handler回调,如果task没有取消,调用此方法。
七、取消
task的取消由cancel(boolean)来完成,当boolean为true时,表明中断线程运行,那么doInBackground运行有可能会被中止并返回。当boolean为false时,不中断doInBackground()方法,而是在执行完成时由handler判断mCancelled状态并回调onCancel()。