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