<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] 關于 Android 源碼分析,引用郭霖老師博客的一段話: > 簡單概括就是八個字:抽絲剝繭、點到即止。應該認準一個功能點,然后去分析這個功能點是如何實現的。但只要去追尋主體的實現邏輯即可,千萬不要試圖去搞懂每一行代碼都是什么意思,那樣很容易會陷入到思維黑洞當中,而且越陷越深。因為這些龐大的系統都不是由一個人寫出來的,每一行代碼都想搞明白,就會感覺自己是在盲人摸象,永遠也研究不透。如果只是去分析主體的實現邏輯,那么就有比較明確的目的性,這樣閱讀源碼會更加輕松,也更加有成效。 本文不是原創,是在閱讀了互聯網上各位大神關于 AsyncTask 源碼分析的文章后,自己對于 AsyncTask 進行的一遍分析,雖不是原創,但自己順著思路捋一遍,并敲下本文后,感覺對于 AsyncTask 的用法以及原理的理解更加深刻了。 本文參考資料: [Android中AsyncTask使用詳解–孫群](http://blog.csdn.net/iispring/article/details/50639090) [Android異步任務AsyncTask的使用與原理分析–開心陽](http://blog.csdn.net/shakespeare001/article/details/51720548) [Android AsyncTask完全解析,帶你從源碼的角度徹底理解–郭霖](http://blog.csdn.net/guolin_blog/article/details/11711405) AsyncTask 的基礎使用 AsyncTask 是一個抽象類,必須寫一個子類繼承它,在子類中完成異步操作。AsyncTask 抽象類指定了3個泛型類型參數: ```java public abstract class AsyncTask<Params, Progress, Result> { ... } ``` 三個泛型類型參數的含義如下: * Params:開始異步任務執行時傳入的參數類型,即 doInBackground()方法中的參數類型; * Progress:異步任務執行過程中,返回進度值的類型,即在 doInBackground 中調用 publishProgress()時傳入的參數類型; * Result:異步任務執行完成后,返回的結果類型,即 doInBackground()方法的返回值類型; AsyncTask 的回調方法包括: * onPreExecute():在執行后臺操作之前調用,運行在主線程中; * doInBackground():核心方法,執行后臺操作的方法,必須實現的一個方法,運行在子線程中; * onPostExecute():后臺操作完成后調用,運行在主線程中; * onProgressUpdate():在下載操作 doInBackground()中調用 publishProgress()時的回調方法,用于更新下載進度,運行在主線程中; # 使用注意事項 * 對于一個 AsyncTack 的實例,只能執行一次 execute 方法,在該實例上第二次執行 execute 方法時就會拋出異常。 * AsyncTask 在最早的版本中用一個單一的后臺線程串行執行多個 AsyncTask 實例的任務,從 Android 1.6(DONUT)開始,AsyncTask 用線程池并行執行異步任務,但是從Android 3.0(HONEYCOMB)開始為了避免并行執行導致的常見錯誤,AsyncTask 又開始默認用單線程作為工作線程處理多個任務。 從Android 3.0開始 AsyncTask 增加了 executeOnExecutor 方法,用該方法可以讓 AsyncTask 并行處理任務,該方法的方法簽名如下所示: ```java public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) ``` 第一個參數表示 exec 是一個 Executor 對象,為了讓 AsyncTask 并行處理任務,通常情況下我們此處傳入 AsyncTask.THREAD_POOL_EXECUTOR 即可,AsyncTask.THREAD_POOL_EXECUTOR 是 AsyncTask 中內置的一個線程池對象,當然我們也可以傳入我們自己實例化的線程池對象。第二個參數 params 表示的是要執行的任務的參數。 # 整體流程 1、首先調用 AsyncTask 的構造方法,構造時對 Handler、WorkerRunnable(Callable) 和 FutureTask 進行初始化 2、然后調用 AsyncTask 的 execute 方法(可以手動設置 Executor,不設置則使用系統默認的 SerialExecutor) 3、首先判斷當前 AsyncTask 狀態,正在運行或者已經運行過就退出 4、調用 onPreExecute 執行準備工作 5、由 Executor 調用 FutureTask 的 run 方法,在 WorkerRunnable 中執行了 doInBackground 6、依舊是在 WorkerRunnable 中,調用 postResult,將執行結果通過 Handler 發送給主線程;調用 publishProgress 時,也是通過 Handler 將消息發送到主線程的消息隊列中 # 源碼解析 開始一個 AsyncTask 任務很簡單,只要執行 new AsyncTask().execute()方法即可。我們的源碼分析也從這里開始。 首先來看 AsyncTask 的構造函數: ```java /** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. */ public AsyncTask() { 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); } } }; } ``` 可以看到,在構造函數中,初始化了兩個變量 mWorker 和 mFuture。首先看看 AsyncTask 的 execute()方法。 ```java @MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } ``` 很簡單,在主線程進行調用,返回 executeOnExecutor(sDefaultExecutor, params)方法的值,那么我們看看這個方法: ```java @MainThread 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.execute(mFuture); return this; } ``` 可以看到,首先對 AsyncTask 的狀態進行了判斷,當 AysncTask 的狀態是 RUNNING 和 FINISHED 時,會拋出異常,這也是為什么一個任務實例只能被啟動一次的原因。executeOnExecutor()方法傳入兩個參數,一個是 Executor,一個是 Params。Params 就是我們執行 doInBackground 中的參數類型。那么 Executor 呢,可以在上一段代碼看到,傳遞來的參數是 sDefaultExecutor,它的初始化如下: ```java public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; ``` 在 executeOnExecutor 方法中我們可以看到,先執行了 onPreExecute()方法,是在主線程。接著執行 exec.execute(mFuture),那么 doInBackground()方法應該就和它有關系了。接下來看看 SerialExecutor 類的 execute 方法,源碼如下: ```java public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } ``` 可以看到,其中執行了參數 Runnable 的 run() 方法,這個 Runnable 就是傳進來的 mFuture。那么看看 FutureTask 的 run()方法: ```java public void run() { if (state != NEW || !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } } ``` 在 run() 方法中執行了 Callable 的 call()方法,callable 又是誰呢,callable 就是在 FutureTask 初始化時傳進來的 mWorker。說明調用的是 mWorker 的 call()方法。去看看: ```java 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; } ``` 在這段代碼中,終于看到我們的 doInBackground()方法,此時依舊是在工作線程中運行。緊接著是 postResult(result),這其中又做了什么呢: ```java private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; } ``` 查看源碼得知,getHandler()返回的是 InternalHandler 的實例對象,那么就要去看看 InternalHandler 的 handleMessage()方法了。 ```java 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; } } ``` 可以看到,當 msg 的 what 值為 MESSAGE_POST_RESULT 時,代表工作線程的任務執行完成,執行 finish()方法。what 值為 MESSAGE_POST_PROGRESS 時,執行 onProgressUpdate(),也就是調用 publishProgress()時的回調方法。看一看 finish() 方法: ```java private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; } ``` 當前任務被取消時,調用 onCancelled()方法,否則調用 onPostExecute()方法。最后看一下 publishProgress()的源碼: ```java @WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } ``` 至此,主要的源碼就看完了,可以看到 AsyncTask 是對 Handler、Message 機制的一種封裝,使得我們的調用更加簡潔。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看