本文章主要講解下AsyncTask的使用以及Hnadler的應用,。 首先,,我們得明確下一個概念,什么是UI線程,。顧名思義,,ui線程就是管理著用戶界面的那個線程! android的ui線程操作并不是安全的,,并且和用戶直接進行界面交互的操作都必須在ui線程中進行才可以,。這種模式叫做單線程模式,。我們在單線程模式下編程一定要注意:不要阻塞ui線程,、確保只在ui線程中訪問ui組件。 當我們要執(zhí)行一個復雜耗時的算法并且最終要將計算結(jié)果反映到ui上時,,我們會發(fā)現(xiàn),,我們根本沒辦法同時保證上面的兩點要求;我們肯定會想到開啟一個新的線程,,讓這個復雜耗時的任務到后臺去執(zhí)行,,但是執(zhí)行完畢了呢?我們發(fā)現(xiàn),,我們無法再與ui進行交互了,。 為了解決這種情況,,android為我們提供了很多辦法。 1),、handler和message機制:通過顯示的拋出,、捕獲信息與ui進行交互; 2),、Activity.runOnUiThread(Runnable):如果當前線程為ui線程,,則立即執(zhí)行;否則,,將參數(shù)中的線程操作放入到ui線程的事件隊列中,,等待執(zhí)行。 3),、View.post(Runnable):將操作放入到message隊列中,,如果放入成功,該操作將會在ui線程中執(zhí)行,,并返回true,,否則返回false 4)、View.postDelayed(Runnable,long)跟第三條基本一樣,,只不過添加了一個延遲時間,。 5)、android1.5以后為我們提供了一個工具類來搞定這個問題AsyncTask. AsyncTask是抽象類.AsyncTask定義了三種泛型類型 Params,,Progress和Result,。 Params 啟動任務執(zhí)行的輸入?yún)?shù),比如HTTP請求的URL Progress 后臺任務執(zhí)行的百分比,。 Result 后臺執(zhí)行任務最終返回的結(jié)果,,比如String 用程序調(diào)用,開發(fā)者需要做的就是實現(xiàn)這些方法,。 1) 子類化AsyncTask 2) 實現(xiàn)AsyncTask中定義的下面一個或幾個方法 onPreExecute(), 該方法將在執(zhí)行實際的后臺操作前被UI thread調(diào)用,。可以在該方法中做一些準備工作,,如在界面上顯示一個進度條,。 doInBackground(Params…), 將在onPreExecute 方法執(zhí)行后馬上執(zhí)行,該方法運行在后臺線程中,。這里將主要負責執(zhí)行那些很耗時的后臺計算工作,。可以調(diào)用 publishProgress方法來更新實時的任務進度,。該方法是抽象方法,,子類必須實現(xiàn)。 onProgressUpdate(Progress…),在publishProgress方法被調(diào)用后,,UI thread將調(diào)用這個方法從而在界面上展示任務的進展情況,,例如通過一個進度條進行展示,。 onPostExecute(Result), 在doInBackground 執(zhí)行完成后,onPostExecute 方法將被UI thread調(diào)用,,后臺的計算結(jié)果將通過該方法傳遞到UI thread. 為了正確的使用AsyncTask類,,以下是幾條必須遵守的準則: 1) Task的實例必須在UI thread中創(chuàng)建 2) execute方法必須在UI thread中調(diào)用 3) 不要手動的調(diào)用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)這幾個方法 4) 該task只能被執(zhí)行一次,,否則多次調(diào)用時將會出現(xiàn)異常
下面介紹最本質(zhì)的多線程:hanlder和message機制: 為何需要多線程: 在日常應用中,,我們通常需要處理一些“后臺,,用戶不可見”的操作,例如說,,我們需要下載一個音樂,,要是你的應用必須等用戶下載完成之后才可以進行別的操 作,那肯定讓用戶非常的不爽,。這時候,,我們通常的做法是,讓這些操作去后臺執(zhí)行,,然后等后臺執(zhí)行完畢之后,,再給用戶彈出相應的提示信息,。這時候,,我們就需 要使用多線程機制,然后通過創(chuàng)建一個新的線程來執(zhí)行這些操作,。 明白了,,實現(xiàn)需求,,我們就準備著手實現(xiàn)了。但是,,經(jīng)過進一步的了解,,我們悲劇的發(fā)現(xiàn),android中的線程機制是,,只能在UI線程中和用戶進行交互,。當 我們創(chuàng)建了一個新線程,執(zhí)行了一些后臺操作,,執(zhí)行完成之后,,我們想要給用戶彈出對話框以確認,但是卻悲劇的發(fā)現(xiàn),,我們根本無法返回UI主線程了,。 (說明:何為UI線程:UI線程就是你當前看到的這些交互界面所屬的線程)。 這時候,,我們?nèi)绻胍獙崿F(xiàn)這些功能,,我們就需要一個android為我們提供的handler和message機制。 先講解下編程機制: 我們通常在UI線程中創(chuàng)建一個handler,,handler相當于一個處理器,,它主要負責處理和綁定到該handler的線程中的message。每一 個handler都必須關(guān)聯(lián)一個looper,,并且兩者是一一對應的,,注意,這點很重要哦,!此外,,looper負責從其內(nèi)部的messageQueue中 拿出一個個的message給handler進行處理。因為我們這里handler是在UI線程中實現(xiàn)的,,所以經(jīng)過這么一個handler,、 message機制,我們就可以回到UI線程中了,。 何為handler:處理后臺進程返回數(shù)據(jù)的工作人員,。 何為message:后臺進程返回的數(shù)據(jù),里面可以存儲bundle等數(shù)據(jù)格式 何為messageQueue:是線程對應looper的一部分,,負責存儲從后臺進程中拋回的和當前handler綁定的message,,是一個隊列。 何為looper:looper相當于一個messageQueue的管理人員,,它會不停的循環(huán)的遍歷隊列,,然后將符合條件的message一個個的拿出來交給handler進行處理。 注意,,handler是在UI線程中聲明的,,如果我們直接用類似代碼執(zhí)行一個線程的話,,實際上并沒有創(chuàng)建一個新的線程,因為handler已經(jīng)跟默認的UI線程中的looper綁定了,。 如果有興趣的話,,可以去看下Handler的默認空構(gòu)造函數(shù)便知道愿意了,里面直接綁定了當前UI線程的looper,。 下面給出一個比較簡單,,并且實用的實例。
轉(zhuǎn)載聲明: 本文轉(zhuǎn)自 Android之多線程工作-AsyncTask與handler |
|