【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )
文章目錄
- 一、AsyncTask 參數簡介
- 二、AsyncTask 方法簡介
- 三、AsyncTask 基本用法
- 四、AsyncTask 構造函數源碼解析
- 五、AsyncTask 構造函數相關源碼注釋
一、AsyncTask 參數簡介
AsyncTask<Void, Void, Void> 泛型類型 :
- 異步任務開始時 , execute() 方法傳入的參數類型 , 也是 doInBackground() 方法傳入的參數類型 ;
- 異步任務執行時 , 進度值類型 , onProgressUpdate() 方法傳入的參數類型 ;
- 異步任務結束時 , 結果類型 , onPostExecute() 方法傳入參數類型 , 或 onCancelled() 方法參數 ;
二、AsyncTask 方法簡介
AsyncTask 常用方法解析 :
- doInBackground() : 核心方法 , 執行異步任務 , 該方法在 子線程 中執行 ;
- onPreExecute() : 在 doInBackground() 執行前先執行的方法 , 主線程 中執行 , 可更新 UI 界面 ;
- onProgressUpdate() : 調用 publishProgress() 回調的方法 , 主線程 中執行 , 可更新 UI 界面 ;
- onPostExecute() : doInBackground() 執行完畢后再執行的方法 , 主線程 中執行 , 可更新 UI 界面 ;
三、AsyncTask 基本用法
AsyncTask 使用注意點 :
- UI 線程創建
- UI 線程調用執行 execute()
- 創建后只能執行一次
自定義 AsyncTask 異步任務 :
package kim.hsl.aa;import android.os.AsyncTask;/*** AsyncTask<String, Integer, Boolean> 泛型解析* - 1. 異步任務開始時 , execute 方法傳入的參數類型* - 2. 異步任務執行時 , 進度值類型* - 3. 異步任務結束時 , 結果類型*/ public class MyAsyncTask extends AsyncTask<String, Integer, Boolean> {@Overrideprotected void onPreExecute() {// doInBackground 之前執行的方法, 一般在該方法中執行初始化操作 ( 主線程, 可以更新 UI )super.onPreExecute();}@Overrideprotected Boolean doInBackground(String... strings) {// 主要的耗時操作是在該方法中執行的 ( 非主線程, 不能更新 UI )return null;}@Overrideprotected void onProgressUpdate(Integer... values) {// 在 doInBackground 中調用了 publishProgress 方法, 就會回調該方法// 一般情況下是在該方法中執行更新 UI 的操作 ( 主線程, 可以更新 UI )super.onProgressUpdate(values);}@Overrideprotected void onPostExecute(Boolean aBoolean) {// doInBackground 執行完畢后 , 調用 return 方法后 , 該方法會被調用 ( 主線程, 可以更新 UI )super.onPostExecute(aBoolean);}@Overrideprotected void onCancelled() {super.onCancelled();}@Overrideprotected void onCancelled(Boolean aBoolean) {super.onCancelled(aBoolean);} }調用異步任務 :
public class MainActivity extends AppCompatActivity {private MyAsyncTask mMyAsyncTask;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 創建并執行異步任務mMyAsyncTask = new MyAsyncTask();mMyAsyncTask.execute();} }四、AsyncTask 構造函數源碼解析
AsyncTask 構造函數作用 : 創建一個新的異步任務 , 該構造函數必須在 UI 主線程調用 ;
構造函數中做了三件事 :
- 獲取 Handler : 該 Handler 是主線程的 Handler ;
- 創建 WorkerRunnable : WorkerRunnable 是實現了 Callable 接口的抽象類 , 該接口中只定義了一個 call() 函數 ;
- 創建 FutureTask : FutureTask 是實現了 RunnableFuture 接口的類 , 該接口中定義了一個 run() 方法 ;
Callable 接口簡介 : Callable 接口實現類定義一個沒有參數的 call 方法 , 該接口與 Runnable 類似 , 兩個接口中都被設計為 , 實現類對象的方法可能被另外一個線程執行
Runnable 與 Callable 接口對比 :
- Runnable 不能返回結果 , 不能拋出檢查過的異常
- Callable 是一個任務 , 返回一個結果 , 并拋出異常 ;
WorkerRunnable<Params, Result> 泛型 :
- Params 是參數類型 , 也是 AsyncTask 的 doInBackground() 方法的輸入參數類型
- Result 是返回值類型 , 也是 AsyncTask 的 doInBackground() 方法的執行完畢的返回值類型
RunnableFuture 接口簡介 : 該接口繼承 Runnable 接口 , Future 接口 ;
-
在普通的 Thread 方法中 , 調用線程的 start() 方法 , 會執行 Thread 對象中的 run() 方法 , 但是方法執行的結果我們是不知道的 ;
-
而在 AsyncTask 異步任務中 , 執行 doInBackground() 方法 , 該方法也是在子線程中執行的 , 可以得到該方法執行的結果 , 這個執行結果是靠 Future 接口得到的 ;
在 WorkerRunnable 中的 call() 方法中執行了 doInBackground() 方法 ;
在 FutureTask 中的 done() 方法中 :
- 執行 postResultIfNotInvoked 方法 : 如果沒有被調用 , 那么傳遞結果 ;
- 執行 postResult() 方法 : 在該方法中使用主線程 Handler 發送 MESSAGE_POST_RESULT 消息 , 觸發 AsyncTask 異步任務的 onPostExecute() 方法
五、AsyncTask 構造函數相關源碼注釋
public abstract class AsyncTask<Params, Progress, Result> {// .../*** 創建一個新的異步任務 . 該構造函數必須在 UI 主線程調用 . * @hide 隱藏方法*/public AsyncTask(@Nullable Looper callbackLooper) {// 獲取 Handler , 用于線程間通信 // 獲取主線程 Looper 對應的 Handler , 或者創建主線程對應 Handler mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()? getMainHandler(): new Handler(callbackLooper);// 創建工作任務 , 該類是 Callable 接口的子類// 實際的 doInBackground() 耗時任務 , 是在該任務中執行的 mWorker = new WorkerRunnable<Params, Result>() {public Result call() throws Exception {mTaskInvoked.set(true);Result result = null;try {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);// 正式執行 doInBackground() 耗時任務 , 在子線程中執行 result = doInBackground(mParams);Binder.flushPendingCommands();} catch (Throwable tr) {mCancelled.set(true);throw tr;} finally {postResult(result);}return result;}};// 未來的任務 mFuture = new FutureTask<Result>(mWorker) {@Overrideprotected 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 void postResultIfNotInvoked(Result result) {final boolean wasTaskInvoked = mTaskInvoked.get();if (!wasTaskInvoked) {// 傳遞結果 postResult(result);}}// 傳遞結果 , 發送 MESSAGE_POST_RESULT 消息 , 該消息會實際上觸發 異步任務 AsyncTask 的 onPostExecute() 方法private Result postResult(Result result) {@SuppressWarnings("unchecked")Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,new AsyncTaskResult<Result>(this, result));message.sendToTarget();return result;}// ... /*** WorkerRunnable 實現 Callable 接口* Callable 是一個任務 , 返回一個結果 , 并拋出異常* 實現類定義一個沒有參數的 call 方法 * 該接口與 Runnable 類似 , 兩個接口中都被設計為 : 實現類對象的方法可能被另外一個線程執行* Runnable 不能返回結果 , 不能拋出檢查過的異常 * * Params 是參數類型 , 也是 AsyncTask 的 doInBackground() 方法的輸入參數類型* Result 是返回值類型 , 也是 AsyncTask 的 doInBackground() 方法的執行完畢的返回值類型 */private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {Params[] mParams;}// ... }
總結
以上是生活随笔為你收集整理的【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android】Source Insi
- 下一篇: 【Android 异步操作】AsyncT