1. 程式人生 > >Android學習筆記十:異步處理

Android學習筆記十:異步處理

cit inb 取消 cti post 動態顯示 模式 一次 工作原理

轉載請註明原文地址: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學習筆記十:異步處理