AsyncTask是个抽象类,需要自定义Task继承,实现其抽象方法。
其底层实现:线程池 + Handler机制
- Params:执行AsyncTask时传入的参数,可用于在后台任务中使用。
- Progress:后台任务执行时,如果需要显示当前的进度,则使用这里指定的泛型作为进度单位。
- Result:当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
public abstract class AsyncTask<Params, Progress, Result> {
@MainThread
protected void onPreExecute() {
//UI线程中,在后台任务开始执行之前调用,可做初始化工作
}
//子线程中,执行耗时任务
@WorkerThread
protected abstract Result doInBackground(Params... params);
@MainThread
protected void onCancelled() {}
@MainThread
protected void onPostExecute(Result result) {}
@MainThread
protected void onProgressUpdate(Progress... values) {}
}
举例子:无返回值,进度值为Integer类型,返回值为Boolean类型
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
……
}
new DownloadTask().execute(); //执行下载任务
AsyncTask实例化
- 默认会创建一个主线程的Handler对象(也可以指定其它线程)
- 构造一个Callable对象,用于执行耗时任务 doInBackground(),并postResult(Result)
- callable封装成一个FutureTask对象
public AsyncTask() {
this((Looper) null);
}
public AsyncTask(@Nullable Looper callbackLooper) {
//不指定looper,默认创建一个主线程的Looper对象
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
//构建一个Callable对象
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result); //返回结果,post到主线程中执行
}
return result;
}
};
//构建一个FutureTask对象
mFuture = new FutureTask<Result>(mWorker);
}
}
执行AsyncTask任务
- 提交任务,放入SerialExecutor 中,等待执行
- SerialExecutor 一次只取一个任务进行执行,通过线程池执行
- 在子线程中执行doInBackground(),并返回执行结果
- 结果默认post到主线程中执行
既然一次只有一个任务执行,为什么要设计这样的线程池?线程复用
execute() 提交任务
- sDefaultExecutor默认为SerialExecutor对象,也可自己指定
- 执行初始化工作
- 在子线程中执行FutureTask
//调用new DownloadTask().execute()
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
//可以指定Executor对象,默认为sDefaultExecutor
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
mStatus = Status.RUNNING;
//在主线程中执行初始化工作
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture); //创建AsyncTask时,实例化mFuture,mWork,用于执行doInBackground()
return this;
}
sDefaultExecutor
- 持有双向队列,用于缓存Runnable对象,
- 静态对象sDefaultExecutor,全局共享,从队尾添加,对头取出来,通过线程池执行
- 按时间顺序串行执行,如果一次有很多任务,需要等上次任务执行完,才取下一个任务执行
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
//全局的,任务按时间顺序串行
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static class SerialExecutor implements Executor {
//双向队列,用于存放Runnable对象
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
//ArrayDeque.offer(e) 在双向队列末尾插入一个元素
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
//等任务执行完,尝试去队列中取下一个任务执行,
scheduleNext();
}
}
});
if (mActive == null) { //默认直接取任务执行,如果已经取到任务,就不会继续scheduleNext()
scheduleNext();
}
}
protected synchronized void scheduleNext() {
//arrayDeque.poll() 从对头取出一个元素,不为null,则通过线程池执行
//如果队列为空,mActive则为null,等待下一个任务的到来
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive); //线程池执行任务
}
}
}
线程池的创建
创建默认线程池:核心线程数大于等于2,小于等于4,核心线程有超时机制,时间也为30s
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
public static final Executor THREAD_POOL_EXECUTOR;
//核心线程数大于等于2,小于等于4,核心线程有超时机制,时间也为30s
//缓冲池,可放入的任务可达128个
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
任务执行结束回调
- getHandler() 默认返回主线程的handler对象(也可指定Handler对象)
- 返回结果,post到handler中执行,默认主线程
- 根据task状态,回调onCancel() 、onPostExecute()
postResult(result); //返回结果,post到主线程中执行
private Result postResult(Result result) {
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
//创建一个主线程的Handler对象
private static Handler getMainHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler(Looper.getMainLooper());
}
return sHandler;
}
}
//已经切换到主线程,根据task状态,回调onCancel() 、onPostExecute()
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
//通过handler机制,发送消息到主线程,处理任务执行完成,和进度更新
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
进度值更新
- 在自定义AsyncTask中调用publishProgress(Progress)
- 如果任务未被取消,则默认发到主线程中,回调onProgressUpdate(Progress)
@WorkerThread
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}