what
android 使用模板模式,封装用于执行异步任务。在android中通常情况下需要实现多线程任务以及UI的更新,但是UI通常情况下只能由UI线程来更新,我们一般简单点可能会使用handler啊,runOnUI方法啊,其实本质也是使用UI主线程的handler。但是写起来很好看不方便,所以android使用handler和线程池封装了一个用于执行异步的AsyncTask。
how
首先看看怎么用吧,巨简单。
继承AsyncTask
三泛型代表:
- Params 输入参数类型
 - Result 执行结果类型
 - Progress 进度量类型
 
依次重写构造方法:
doInBackground具体任务执行onPreExecute任务之前,UI线程,一般用于添加执行开始提示onPostExecute任务执行之后,UI线程,用于添加执行完成提示onProgressUpdate进度变化回调,UI线程,用于添加进度提示
1  | 
  | 
新建实例,执行
这个是使用默认线程池,会去排队的哦(串行执行)
1  | new DeleteAsyncTask().execute(mSelectedList);  | 
你要觉得不爽,或者你的任务很特别是那种IO任务啊,或者计算任务啊。指定你的线程池
1  | new DeleteAsyncTask().executeOnExecutor(executor,mSelectedList);  | 
why
首先讲下为啥以execute(paramm)的方式执行AsyncTask是串行的执行的。为啥呢,因为AsyncTask内部是维持了两个线程池,SERIAL_EXECUTOR:用于任务排队即所有任务顺序执行的线程池。THREAD_POOL_EXECUTOR:用于实际执行任务的线程池,调用execute时会通过SERIAL_EXECUTOR来执行,而这个则是入队列,然后调用THREAD_POOL_EXECUTOR来实际执行任务。对了他们都是静态的。
AsyncTask状态
1  | public enum Status {  | 
SERIAL_EXECUTOR线程池
1  | private static class SerialExecutor implements Executor {  | 
THREAD_POOL_EXECUTOR 线程池
1  | public static final Executor THREAD_POOL_EXECUTOR;  | 
InternalHandler
1  | private static class InternalHandler extends Handler {  | 
首先从构造方法看
最终都会调用参数为Looper的构造方法,在构造方法里面进行获得UI handler,以及初始化CallAble和FutureTask
1  | public AsyncTask() {  | 
看execute执行
1  | public final AsyncTask<Params, Progress, Result> execute(Params... params) {  | 
走向executeOnExecutor,当然我们也可以调,这个就是说让任务在传入的线程池中运行
首先判断标志位是否合格,也就是执行过的或者执行完的都不能再次执行了。回调onPreExecute,然后添加参数进入线程池
1  | public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,  | 
来到串行线程池
将任务入队列,顺序执行,调用实际的线程池
1  | private static class SerialExecutor implements Executor {  | 
几个回调
doInBackground
在Callable中执行的
1  | mWorker = new WorkerRunnable<Params, Result>() {  | 
onPreExecute
在任务进入线程池之前执行
1  | mStatus = Status.RUNNING;//修改状态  | 
onPostExecute
handler发送结果后finish中执行
1  | private void finish(Result result) {  | 
onProgressUpdate
在手动调用publishProgress,handler发送消息
1  | protected final void publishProgress(Progress... values) {  | 
onCancelled
使用cancel,取消任务
1  | public final boolean cancel(boolean mayInterruptIfRunning) {  |