AsyncTask的學習java
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT(API level1.6), this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB(API level3.0), tasks are executed on a single thread to avoid common application errors caused by parallel execution. If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.android
1.6以前的AsyncTask在一個後臺線程中串行serially,app
後來1.6之後又在一個線程池中並行.ide
再後來的3.0以後又只在一個線程中執行了.因此全部的AsyncTask都會排隊.可是你也能夠調用executeOnExecutor(Executor)傳入你的線程池而後去並行這些任務.oop
AsyncTask爲何後來要改爲串行? 同一個進程中的AsyncTask使用的都是一個線程池.那麼若是是並行的. 當A,B兩個AsyncTask的doInbackGround方法都訪問操做了同一個資源的話就煞筆了. 通常不會有人記得去synchronized一把doInbackground方法吧.
post
看這個東西是想知道爲何剛開始AsyncTask的任務都是並行的?學習
public final AsyncTask<Params, Progress, Result> execute(Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; sExecutor.execute(mFuture); return this; }
關於這個sExecutor的聲明以下:因此很容易看出來這些任務都是在這個線程池中並行的.this
private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 10; private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(10); 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 ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
後來的代碼變成了默認串行,是由於這段代碼嗎? synchronized致使這個方法只會同時有一個線程進入. 必須等這個線程執行完了纔會釋放鎖讓其餘線程有機會進入execute方法. 那爲何真正執行線程代碼的地方線程池的核心線程要超過一個? 不是串行麼?一個不就夠了嗎? ``` private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } } ```
android4.1.1
的代碼.在ActivityThread這個類的main方法中有以下:線程
public static void main(String[] args) { ... AsyncTask.init(); }
這一樣的4.1.1的AsyncTask的代碼中code
首先這個sHandler的聲明以下
private static final InternalHandler sHandler = new InternalHandler(); //Used to force static handler to be created. public static void init() { sHandler.getLooper(); }
這個InternalHandler是AsyncTask的一個內部類的代碼以下:
private static class InternalHandler extends Handler { @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; } } }
可是在5.1(API level22)
之後這些有一點點變化 首先AsyncTask的init靜態方法被去除了. 而後就是sHandler在聲明的時候是空,後續操做該handler都經過getHander()方法.
private static InternalHandler sHandler; private static Handler getHandler() { //這裏爲啥不像double check似的寫啊. synchronized (AsyncTask.class) { if (sHandler == null) { sHandler = new InternalHandler(); } return sHandler; } }
而後這個InternalHandler的內容和以前有了一個點小小的改變
private static class InternalHandler extends Handler { //這裏是重點確保該handler的looper爲主線程的looper public InternalHandler() { super(Looper.getMainLooper()); } @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @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; } } }
注意這個構造方法super(Looper.getMainLooper())這個就確保了這個sHandler的Looper必定是主線程的Looper. 那麼經過這個sHandler發送的消息的handleMessage方法必定在主線程執行. 因此在這個時候after API level22
繼承AsyncTask的實例就無需在主線程實例化了.
AsyncTask的構造方法代碼
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(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); } } }; } private final WorkerRunnable<Params, Result> mWorker; private final FutureTask<Result> mFuture;
這裏的WorkRunnable代碼以下:
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }
可見這就是一個Callable. 下面開始跟蹤代碼.從
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
這個sDefaultExecutor的聲明是這個樣子:
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; //這裏的exec就是上面的sDefaultExecutor //mFuture就是構造方法建立的那個FutureTask exec.execute(mFuture); return this; }
而後再到SerialExecutor
private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); //A start if (mActive == null) { scheduleNext(); } //A end } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }
SerialExecutor原本就是串行的線程池的意思. 它只負責把runnable放到mTasks中. execute方法中把new的runnable加入mTasks. 至於這個runnnable執行的內容先無論. 而後就到了代碼段A.剛開始的時候mActive變量必須是null因此會執行scheduleNext()方法.而後這個方法裏會從mTasks中取出東西並賦值給mActive變量. 並把這個mActive放到THREAD_POOL_EXECUTOR中執行.
到這裏會先直接調用傳入Runnable的run方法. 就是執行mFuture的run方法.
大概的瞭解:FutureTask實現了Runnnable接口.調用run方法會致使 構造該FutureTask的callable的call方法被調用.
因此到了這裏構造方法中的WorkerRunnable的call方法就會被調用.該call方法以下:
public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); }
到了這裏AsyncTask的doInBackground(mParams)方法就被調用了.並且是在THREAD_POOL_EXECUTOR這個線程池中執行.
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; 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);
而後接着的代碼
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
把doInbackground方法的結果經過handler進行發送.而後看handler的handleMessage方法.
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; } }
這裏的result.mTask就是AsyncTask.見代碼
private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }
因此代碼就到了AsyncTask的finish方法.
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
到這裏就看到onPostExecute方法裏,就差很少了.