一、核心思想
AsyncTask 提供一個(gè)根據(jù)CPU核心數(shù)來(lái)確定的一個(gè)線程池,任務(wù)通過(guò)FutureTask提交給線程池執(zhí)行。任務(wù)執(zhí)行進(jìn)度和結(jié)果通過(guò)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 }
根據(jù)源碼可知,線程池的初始化根據(jù)當(dāng)前設(shè)備的CPU核心數(shù)來(lái)確定核心線程數(shù)和最大線程數(shù)的。
- 初始化串行執(zhí)行器
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
這個(gè)串行執(zhí)行器維護(hù)了一個(gè)Runnable隊(duì)列,負(fù)責(zé)將全局的任務(wù)串行的提交到線程池中執(zhí)行。
- 將任務(wù)提交到串行執(zhí)行器的任務(wù)隊(duì)列。
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 }
這里的參數(shù)exec實(shí)際上就是SerialExecutor的一個(gè)對(duì)象。我們看下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實(shí)現(xiàn)了Callable接口,它和Runnable的區(qū)別參考這篇文章。mFuture是一個(gè)FutureTask對(duì)象,這個(gè)類實(shí)現(xiàn)了Runnable接口所以能提交到線程池執(zhí)行,同時(shí)它實(shí)現(xiàn)了Future接口,所以能獲得執(zhí)行結(jié)果。至于為什么可參考FutureTask源碼
- 執(zhí)行結(jié)果的回調(diào)
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 }
通過(guò)上面代碼可以知道,AsyncTask獲得了主線程的Looper,并將執(zhí)行結(jié)果回調(diào)到了主線程。