一、AsyncTask简单介绍
AsyncTask作用:轻量级的异步类,方便在子线程中更新ui
AsyncTask方法介绍:
onPreExecute():任务执行前调用的方法,可用于做一些准备工作
doInBackground(Object[] objects):异步执行方法,一般用于处理耗时操作
onPostExecute(Object o):异步执行结束后的操作,在主线程中执行,可执行ui操作
简单使用示例:
public class TestAsyncTask extends AsyncTask<String,Integer,Boolean> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Boolean doInBackground(String[] objects) { String name0 = (String)objects[0]; String name1= (String)objects[1]; Log.d("test",name0 + " threadId:" + Thread.currentThread().getId() + " time:"+ System.currentTimeMillis()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Log.d("test",name1 + " threadId:"+ Thread.currentThread().getId() + " time:"+ System.currentTimeMillis()); return true; } @Override protected void onPostExecute(Boolean o) { super.onPostExecute(o); Log.d("test","" + (boolean)o + " threadId:" + Thread.currentThread().getId() + " time:"+ System.currentTimeMillis()); } }
调用示例:
TestAsyncTask task = new TestAsyncTask(); task.execute("test1","test2");
运行打印结果:
二、AsyncTask原理解释
2.1 、申明
AsyncTask<Params, Progress, Result>
参数解释:
Params:启动任务时传入的参数,举例中设置为String,也可设置为其他类型
Progress:任务执行中的进度,一般设置为integer,表示当前处理的进度
Result:处理结果参数,举例中使用的是Boolean
2.2、重要的静态变量
2.2.1、sThreadFactory
AsyncTask重要元素之一,为AsyncTask的线程池创建线程,执行newThread方法的时候会创建线程
2.2.2、HREAD_POOL_EXECUTOR
定义了一个线程池,线程池 ,注意ThreadPoolExecutor的构造,会将sThreadFactory 存放在成员变量threadFactory,CORE_POOL_SIZE 为1,进程中所有AsyncTask的对象依赖的线程只有一个,按照顺序排队执行task。
2.2.3、SerialExecutor
SerialExecutor的execute方法做了以下两个步骤
1、new了一个runnable对象,并在run方法中执行了参数中runnable的run方法
2、判断mActive是否为空,去执行添加到mTasks中的runnable
2.2.4、mWorker
mWorker,归根结底,就是一个Callable对象,我们再来看他的实现:
注意在他的call方法中执行了doInBackground方法。
2.2.5、mFuture
mFuture,从源头上是实现Runnable以及Future,所以mFuture需要实现Runnable 的run(),也是实现Future的cancel等方法
我们来看一下mFuture的实现以及run方法:
实现mFuture的时候,把mWorker当做了参数并在mFuture中保存了下来,在mFuture的run方法中调用了mWorker.call()方法
2.3、整体流程介绍
调用AsyncTask.execute(Params... params)方法会执行到以下方法,
在执行execute()方法之前做了两件事情:
1、执行onPreExecute()做准备工作
2、赋值params给到mWorker.mParams,供2.2.4中调用doInBackground方法使用
exec对应的是sDefaultExecutor,也就是2.2.3中的SerialExecutor,将2.2.5中的mFuture添加到了SerialExecutor的生成的runnable中,并将生成的runnable添加进了mTasks,调用了THREAD_POOL_EXECUTOR也就是线程池的execute方法。
下面来看线程池的execute方法:
再进入addWorker方法:
以及work的构造方法:
利用2.2.1中的sThreadFactory,去生成了一个thread,并在addworker中执行了thread的run方法。
(说明:work本身也是一个runnable,在run方法中执行了firstTask的run方法)
这样就实现了在新的线程中调用传入的mFuture的run方法,也就是调用了mWorker的call方法,让doInBackground方法在新的线程中执行,实现了异步
2.4、如何实现结果回调到主线程
这儿要注意到另一个金泰变量:sHandler
注意这儿是使用主线程中的looper构造的handler,
在任务执行完之后会调用postResult方法:
在这个方法中,利用handler发送了消息,实现了在主线程中回调onPostExecute或者onCancelled方法。
2.5、最后介绍一下cancel方法防止踩坑
cancel方法如下:
做了两件事:
1、设置 mCancelled为true
2、调用mFuture.cancel()方法
mFuture.cancel()中调用了t.interrupt(),注意t.interrupt()只是尝试去让线程结束,但并不一定能真的结束,所以不能已调用了AsyncTask的cancel方法,判断任务已结束,建议在任务的流程中通过mCancelled这个标识,主动去结束自己的任务流程,比如任务是一个循环,可在循环的时候判断mCancelled为true,去结束循环,进而结束任务