在Android多线程之Handler中,我们举例说明处理耗时任务可以通过Java Thread来实现。但是Thread创建系统资源上开销很大,同时也不好管理销毁, 尤其是在多并发的情况下,问题更为严重。Android为此提供了AsyncTask。
查看AsyncTask源码,发现它内部是开启了一个并发量为128,CORE_POOL_SIZE和MAXIMUM_POOL_SIZE根据设备动态计算的ThreadPoolExecutor线程池。
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;
}
AsyncTask构造的时候,初始化了mHandler,mWorker和mFuture三个成员变量,mHandler的Looper必须是getMainHandler。
public AsyncTask(@Nullable Looper callbackLooper) {
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
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);
}
return result;
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
当AsyncTask调execute()方式的时候,会触发源码executeOnExecutor方法。默认构造的Executor此时就开始执行FutureTask任务,后台耗时任务放在WorkerRunnable的call方法中执行。
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
...
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
后台任务执行完成之后通过postResult()方法把结果抛到主线程。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
主要方法:
-
execute()
开始执行AsyncTask,默认是初始化构造的线程池执行。提供executeOnExecutor(…)传入自定义的线程池。
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
-
onPreExecute()
处理异步任务前的准备工作(UI线程)
-
doInBakground()
处理异步任务的方法
-
onPostExecute()
异步任务处理结束的回调(UI线程)
-
onProgressUpdate()
用来更新异步任务的进度,必须在doInBakground()自己手动调取publishProgress()来发送数据.
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
-
cancel(...)
手动取消任务,因为默认的线程池长度是固定死的,所以最好及时调用cancel取消任务。否则极端场景超过了线程池最大容量会报异常。
-
execute(runnable)
静态方法,提供直接利用AsyncTask定义好的线程池来执行异步任务。
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}