標籤:類的設計 sdn post blog int 結果 upd 設定 情境
轉載請註明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html
一:基礎概念
UI線程:當Android程式第一次啟動時,Android會同時啟動一條主線程(Main Thread),主線程主要負責處理與UI相關的事件,如使用者的按鍵事件、螢幕繪圖事件,並把相關的事件分發到對應的組件進行處理。主線程通常又被稱為UI線程,Android只允許UI線程修改Activity裡的UI組件。
子線程:在程式的activity中建立、啟動的線程為子線程,子線程中不能操作UI組件。
背景工作:背景工作一般用子線程來完成,通常用於執行一些耗時任務如:複雜計算、下載檔案等。因為這些操作是與UI線程同時運作的,所以又稱為非同步作業。
二:非同步方式之——訊息傳遞機制
我們知道,只有UI線程才能修改、操作介面組件,那麼其他子線程中的資訊如何反映到UI中呢?那就需要子線程把資訊匯總到UI線程,由UI線程顯示到組件上。
這個過程,就是訊息傳遞機制。
1)訊息傳遞機制原理圖
2)訊息傳遞機制解釋
首先,UI線程中維護一個訊息佇列MessageQueue、一個迴圈者Looper、一個處理者Handler:訊息佇列負責接受、儲存其他子線程發送過來的訊息,等待UI線程處理;迴圈者不停地輪詢訊息佇列,每次都提取隊首一個訊息;處理者負責處理Looper提取出來的訊息,並負責把結果在UI進行呈現。其中,MessageQueue和Looper隨著UI線程啟動而自動建立並運行,Handler則需要手動定義。
其次,在UI線程中建立並啟動子線程,子線程中通過同一個handler(通常這個handler為acticity代碼中的全域變數,因此子線程中可見)來發送訊息,從而把訊息發送到了當前UI線程的handler對應的訊息佇列中。
3)實現步驟
根據訊息傳遞機制的原理,我們只需針對實現各個環節需要的東西即可。
首先:定義、建立Handler,重寫其中的handlerMessage方法,處理訊息
private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { //根據訊息內容,作處理 } } };
然後:定義子線程,在其中定義發送訊息語句
Runnable runnable = new Runnable() { @Override public void run() { Message message = new Message(); message.what = 訊息標籤; mHandler.sendMessage(message); //handler是UI線程中的handler } };
最後:根據條件,建立子線程執行個體並啟動
mThread = new Thread(runnable); mThread.start();
4)應用情境
Handler機制適合多個子線程存在的情況,這樣可以把多個子線程發送過來的資訊在UI線程中統一處理、繪製呈現。
【附:如果需要在子線程中使用handler和looper,則需要擷取到UI線程中的handler、looper對象。具體方法見:http://blog.csdn.net/logicteamleader/article/details/46591499】
三:單個非同步任務——AsyncTask
訊息傳遞機制看起來比較複雜,涉及到了訊息佇列的應用,這幾乎是大型Web應用的架構層面才會用到的模式了。
如果只是單個的非同步任務,用訊息傳遞機制就有些過於麻煩了,為此,Android為我們提供了一個輔助類——AsyncTask。
AsyncTask類,可以理解為非同步任務執行者;這個類的設計目的很明確,就是為了“執行一個較為耗時的非同步任務(最多幾秒鐘),然後更新介面”。
1:使用AsyncTask
1)繼承AsyncTask,定義子類,重寫其中的幾個方法:
AsyncTask需要重寫5個方法,分別是:
1、onPreExecute方法:準備運行,該回呼函數在任務被執行之後立即由UI線程調用,一般可以顯示進度條。
2、doInBackground(Params ...)方法:正在後台運行,通常在這裡執行耗時的後台計算,計算結果返回給函數,這裡如果AsyncTask的第三個參數是Void的話不需要返回,這裡不能更新UI,但是可以調用publishProgress(Progress ...)方法完成。
3、onProgressUpdate(Progress ...)方法:進度更新,UI線程在publishProgress(Progress ...)方法調用完成後被調用,一般動態顯示一個進度。
4、onPostExecute(Result)方法:完成背景工作,會返回,這裡可以進行些UI的操作,比如提醒任務執行的結果,以及關閉掉進度條對話方塊等。
5、onCancelled方法:取消任務,在調用AsyncTask的cancel()方法的時候調用。
class ViewContentTask extends AsyncTask<Void, Integer, Boolean> {//三個範型分別對應下面doInBackground、onProgressUpdate、onPostExecute三個方法的參數類型 @Override protected Boolean doInBackground(Void... voids) { return null; } @Override protected void onProgressUpdate(Integer... values) { } @Override protected void onPostExecute(Boolean b) { //操作UI組件 } @Override protected void onPreExecute() { } @Override protected void onCancelled() { } }
2)建立非同步任務執行個體,啟動非同步任務
ViewContentTask task = new ViewContentTask(); task.execute();
2:AsyncTask工作原理
當一個非同步任務被執行時,要經曆四步:
onPreExecute(),在UI線程中執行,它會在非同步任務開始前執行,一般用來設定任務參數;
doInBackground, 最重要的方法,在子線程中執行(事實上,只有它在子線程中執行,其他方法都在UI線程中執行)。當onPreExecute結束後,本方法立刻執行,它用 來進行背景耗時計算,非同步任務的參數會被傳給它,執行完成的結果會被送給第四步;執行途中,它還可以調用publishProgress 方法來通知UI線程當前執行的進度;
onProgressUpdate, 當publishProgress 被調用後,它在UI線程中執行,重新整理任務進度,一般用來重新整理進度條等UI組件;
onPostExecute, 當背景非同步任務完成後,它會在UI線程中被調用,並擷取非同步任務執行完成的結果。
Android學習筆記十:非同步處理