Android AsyncTask源碼分析

一、核心思想

AsyncTask 提供一個(gè)根據(jù)CPU核心數(shù)來(lái)確定的一個(gè)線程池,任務(wù)通過(guò)FutureTask提交給線程池執(zhí)行。任務(wù)執(zhí)行進(jìn)度和結(jié)果通過(guò)Handler拋出。

二、看源碼

  1. 初始化線程池
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ù)的。

  1. 初始化串行執(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í)行。

  1. 將任務(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源碼

  1. 執(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)到了主線程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容