一、核心思想
AsyncTask 提供一个根据CPU核心数来确定的一个线程池,任务通过FutureTask提交给线程池执行。任务执行进度和结果通过Handler抛出。
二、看源码
- 初始化线程池
183 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
184 // We want at least 2 threads and at most 4 threads in the core pool,
185 // preferring to have 1 less than the CPU count to avoid saturating
186 // the CPU with background work
187 private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
188 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
189 private static final int KEEP_ALIVE_SECONDS = 30;
190
191 private static final ThreadFactory sThreadFactory = new ThreadFactory() {
192 private final AtomicInteger mCount = new AtomicInteger(1);
193
194 public Thread newThread(Runnable r) {
195 return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
196 }
197 };
198
199 private static final BlockingQueue<Runnable> sPoolWorkQueue =
200 new LinkedBlockingQueue<Runnable>(128);
201
202 /**
203 * An {@link Executor} that can be used to execute tasks in parallel.
204 */
205 public static final Executor THREAD_POOL_EXECUTOR;
206
207 static {
208 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
209 CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
210 sPoolWorkQueue, sThreadFactory);
211 threadPoolExecutor.allowCoreThreadTimeOut(true);
212 THREAD_POOL_EXECUTOR = threadPoolExecutor;
213 }
根据源码可知,线程池的初始化根据当前设备的CPU核心数来确定核心线程数和最大线程数的。
- 初始化串行执行器
235 private static class SerialExecutor implements Executor {
236 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
237 Runnable mActive;
238
239 public synchronized void execute(final Runnable r) {
240 mTasks.offer(new Runnable() {
241 public void run() {
242 try {
243 r.run();
244 } finally {
245 scheduleNext();
246 }
247 }
248 });
249 if (mActive == null) {
250 scheduleNext();
251 }
252 }
253
254 protected synchronized void scheduleNext() {
255 if ((mActive = mTasks.poll()) != null) {
256 THREAD_POOL_EXECUTOR.execute(mActive);
257 }
258 }
259 }
260
这个串行执行器维护了一个Runnable队列,负责将全局的任务串行的提交到线程池中执行。
- 将任务提交到串行执行器的任务队列。
603 @MainThread
604 public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
605 Params... params) {
606 if (mStatus != Status.PENDING) {
607 switch (mStatus) {
608 case RUNNING:
609 throw new IllegalStateException("Cannot execute task:"
610 + " the task is already running.");
611 case FINISHED:
612 throw new IllegalStateException("Cannot execute task:"
613 + " the task has already been executed "
614 + "(a task can be executed only once)");
615 }
616 }
617
618 mStatus = Status.RUNNING;
619
620 onPreExecute();
621
622 mWorker.mParams = params;
623 exec.execute(mFuture);
624
625 return this;
626 }
这里的参数exec实际上就是SerialExecutor的一个对象。我们看下mFuture和mWorker的初始化
297 public AsyncTask() {
298 mWorker = new WorkerRunnable<Params, Result>() {
299 public Result call() throws Exception {
300 mTaskInvoked.set(true);
301 Result result = null;
302 try {
303 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
304 //noinspection unchecked
305 result = doInBackground(mParams);
306 Binder.flushPendingCommands();
307 } catch (Throwable tr) {
308 mCancelled.set(true);
309 throw tr;
310 } finally {
311 postResult(result);
312 }
313 return result;
314 }
315 };
316
317 mFuture = new FutureTask<Result>(mWorker) {
318 @Override
319 protected void done() {
320 try {
321 postResultIfNotInvoked(get());
322 } catch (InterruptedException e) {
323 android.util.Log.w(LOG_TAG, e);
324 } catch (ExecutionException e) {
325 throw new RuntimeException("An error occurred while executing doInBackground()",
326 e.getCause());
327 } catch (CancellationException e) {
328 postResultIfNotInvoked(null);
329 }
330 }
331 };
332 }
WorkerRunnable实现了Callable接口,它和Runnable的区别参考这篇文章。mFuture是一个FutureTask对象,这个类实现了Runnable接口所以能提交到线程池执行,同时它实现了Future接口,所以能获得执行结果。至于为什么可参考FutureTask源码
- 执行结果的回调
341 private Result postResult(Result result) {
342 @SuppressWarnings("unchecked")
343 Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
344 new AsyncTaskResult<Result>(this, result));
345 message.sendToTarget();
346 return result;
347 }
280 private static Handler getHandler() {
281 synchronized (AsyncTask.class) {
282 if (sHandler == null) {
283 sHandler = new InternalHandler();
284 }
285 return sHandler;
286 }
287 }
672 private static class InternalHandler extends Handler {
673 public InternalHandler() {
674 super(Looper.getMainLooper());
675 }
676
677 @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
678 @Override
679 public void handleMessage(Message msg) {
680 AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
681 switch (msg.what) {
682 case MESSAGE_POST_RESULT:
683 // There is only one result
684 result.mTask.finish(result.mData[0]);
685 break;
686 case MESSAGE_POST_PROGRESS:
687 result.mTask.onProgressUpdate(result.mData);
688 break;
689 }
690 }
691 }
通过上面代码可以知道,AsyncTask获得了主线程的Looper,并将执行结果回调到了主线程。