2019年6月3日 星期一

[Android] AsyncTask 用法詳解

簡述:

Android 的 App, 通常只在預設的 UI Thread 運行. 當遇到一些較為耗費時間的工作時, 就必須採用 Multi Thread  的作法. 否則很容易就會遇到 ANR 的錯誤, 導致 App 被停止執行. AsyncTask 是一種 Multi Thread 的作法.

AsyncTask 的型態:

因為 AsyncTask 的目的就是提供一個線外作業的機制, 所以它會有兩個特性:  
  1. 在平行時間運行. AsyncTask 和 UI Thread 必須可以在不互相影響的狀況下各自運行.
  2. 互動. AsyncTask 的運行必須可以反映到  UI Thread (如果不能反映到 UI Thread, 又怎麼知道它執行完畢了呢 ?)
於是, 很容易可以猜想到, AsyncTask  它會接收一個起始狀態, 一個運行狀態, 一個結果回報的狀態. 這3 種狀態的參數型態,  就是這個 AsnycTask 的參數型態, 如下圖:
 
class SleepTask extends AsnycTask<String, Integer, String>, 這邊就宣告了 SleepTask 是 AsyncTask 的衍生類別, 它有 3 個參數型態, String, Integer, String. 各參數依序為起始狀態, 運行狀態, 結果狀態.
起始狀態是在執行時, 由呼叫程序傳入, 然後 AsnycTask 在呼叫 doInBackground 時, 以參數傳入. 從字面上的意義可以知道, doInBackground 是真正在計算的苦力. doInBackground  接收到起始狀態, 然後照起始狀態的指示, 開始運算. 算到一個階段 (需要通知 UI Thread 進度的時候),  就呼叫 publishProgress, 並給予運行狀態, 以便回報進度.  AsyncTask 再把這各參數轉送到 onProgressUpdate. 計算結束的時候, doInBackground 的返回值也會被送到 onPostExcute, 以便更新運算的結果.
之所以要這麼麻煩, 是因為 AsyncTask 除了要運行 doInBackground() 這個苦力程序外, 還要負責同步狀態到 UI Thread. 所以就有了 onPreExecute()/onProgressUpdate()/onPostExecute(), 這三個程序, 用來在不同的時間點更新 UI Thread. 其中除了 onPreExecute 不需要參數, onProgressUpdate()/onPostExecute() 都是把 doInBackground() 產生的狀態更新到 UI Thread.

AsyncTask 的成員函式:

衍生的 AsnycTask 類別, 需要實作以下函式
onPreExecute(), 在還沒有開始計算前, 負責準備工作.
doInBackground(), 真正的苦力運算函式.
onProgressUpdate(), 協助更新 doInBackground 的運算進度
onPostExecute(), 協助更新 doInBackground 的運算結果.

沒有留言:

張貼留言

[ NT98515] CROSSCOMPILE ECLIPSE PAHO MQTT C Client

簡述: 試著把 Eclipse Paho MQTT C client  移植到 NT98515 的平台, 並且測試驗證. 下載 source: git clone https://github.com/eclipse/paho.mqtt.c make: cmake $ cmake...