Android的UI線程主要負責處理用戶的按鍵事件、用戶觸屏事件及屏幕繪圖事件等,因此開發者的其他操作不應該、也不能阻塞UI線程,否則UI界面將會變得停止響應——用戶感覺非常糟糕。(總之,開發者需要牢記:不要再UI線程中執行一些耗時的操作)。 為了避免UI線程失去響應的問題,Android建議將耗時
Android的UI線程主要負責處理用戶的按鍵事件、用戶觸屏事件及屏幕繪圖事件等,因此開發者的其他操作不應該、也不能阻塞UI線程,否則UI界面將會變得停止響應——用戶感覺非常糟糕。(總之,開發者需要牢記:不要再UI線程中執行一些耗時的操作)。
為了避免UI線程失去響應的問題,Android建議將耗時操作放在新線程中完成,但新線程也可能需要動態更新UI組件:比如需要從網上獲取一個網頁,然後再TextView中將其源代碼顯示出來,此時就應該將連接網路、獲取網路數據的操作放在新線程中完成。問題是:獲取網路數據之後,新線程不允許直接更新UI組件。
為瞭解決新線程不能更新UI組件的問題,Android提供瞭如下幾種解決方案:
1、使用Handler實現線程之間的通信.
2、Activity.runOnUiThread(Runnable).
3、View.post(Runnable).
4、View.postDelayed(Runnable,long).
後面三種方式可能導致編程略顯煩瑣,而非同步任務(AsyncTask)則可進一步簡化這種操作。
AsyncTask<>是一個抽象類,通常用於被繼承,繼承 AsyncTask 時需要指定如下三個泛型參數。
相對來說 AsyncTask 更輕量一些,適用於簡單的非同步處理,不需要藉助線程和Handler即可實現。
AsyncTask<Params,Progress,Result>是抽象類,它定義瞭如下三種泛型類型。
1、Params:啟動任務執行的輸入參數的類型
2、Progress:後臺任務完成的進度值的類型
3、Result:後臺執行任務完成後返回結果的類型。
使用AsyncTask只要如下三步即可。
1、創建 AsyncTask 的子類,併為三個泛型參數指定類型。如果某個泛型參數不需要指定類型,可將它指定為Void
2、根據需要,實現 AsyncTask 的如下方法:
2.1、doInBackground(Params...):重寫該方法就是後臺線程將要完成的任務。該方法可以調用publishProgress(Progress..values)方法更新任務的執行進度。
2.2、onProgressUpdate(Progress...values):在doInBackground()方法中調用publishProgress()方法更新任務的執行進度後,將會觸發該方法。
2.3、onPreExecute():該方法將在執行後臺耗時操作前被調用。通常該方法用於完成一些初始化的準備工作,比如在界面上顯示進度條等。
2.4、onPostExecute(Result result):當doInBackground()完成後,系統會自動調用onPostExecute()方法,並將doInBackground()方法的返回值傳給該方法.
3、調用 AsyncTask 子類的實例 execute(Params ... params)開始執行耗時任務。
使用AsyncTask 是必須遵守如下規則
1、必須在UI線程中創建 AsyncTask 的實例
2、必須在UI線程中調用 AsyncTask 的execute()方法
3、AsyncTask 的 onPreExecute()、onPostExecute(Result result)、doInBackground(Params... params),onProgressUpdate(Progress...values)方法,不應該由程式員代碼調用,而是由Android系統負責調用。
4、每個 AsyncTask 只能被執行一次,多次調用將會引發異常。