* AsyncTask
看上去修改后的connect()方法已經(jīng)可用了,但是這種匿名線程的方式是存在缺陷的:第一,線程的開銷較大,如果每個任務(wù)都要創(chuàng)建一個線程,那么應(yīng)用 程序的效率要低很多;第二,線程無法管理,匿名線程創(chuàng)建并啟動后就不受程序的控制了,如果有很多個請求發(fā)送,那么就會啟動非常多的線程,系統(tǒng)將不堪重負。 另外,前面已經(jīng)看到,在新線程中更新UI還必須要引入handler,這讓代碼看上去非常臃腫。
為了解決這一問題,OPhone在1.5版本引入了AsyncTask。AsyncTask的特點是任務(wù)在主線程之外運行,而回調(diào)方法是在主線程中執(zhí)行, 這就有效地避免了使用Handler帶來的麻煩。閱讀AsyncTask的源碼可知,AsyncTask是使用java.util.concurrent 框架來管理線程以及任務(wù)的執(zhí)行的,concurrent框架是一個非常成熟,高效的框架,經(jīng)過了嚴格的測試。這說明AsyncTask的設(shè)計很好的解決了 匿名線程存在的問題。
AsyncTask是抽象類,子類必須實現(xiàn)抽象方法doInBackground(Params... p) ,在此方法中實現(xiàn)任務(wù)的執(zhí)行工作,比如連接網(wǎng)絡(luò)獲取數(shù)據(jù)等。通常還應(yīng)該實現(xiàn)onPostExecute(Result r)方法,因為應(yīng)用程序關(guān)心的結(jié)果在此方法中返回。需要注意的是AsyncTask一定要在主線程中創(chuàng)建實例。AsyncTask定義了三種泛型類型 Params,Progress和Result。
* Params 啟動任務(wù)執(zhí)行的輸入?yún)?shù),比如HTTP請求的URL。
* Progress 后臺任務(wù)執(zhí)行的百分比。
* Result 后臺執(zhí)行任務(wù)最終返回的結(jié)果,比如String。
AsyncTask 的執(zhí)行分為四個步驟,與前面定義的TaskListener類似。每一步都對應(yīng)一個回調(diào)方法,需要注意的是這些方法不應(yīng)該由應(yīng)用程序調(diào)用,開發(fā)者需要做的就是實現(xiàn)這些方法。在任務(wù)的執(zhí)行過程中,這些方法被自動調(diào)用。
* onPreExecute() 當任務(wù)執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進度對話框。
* doInBackground(Params...) 此方法在后臺線程執(zhí)行,完成任務(wù)的主要工作,通常需要較長的時間。在執(zhí)行過程中可以調(diào)用publicProgress(Progress...)來更新任務(wù)的進度。
* onProgressUpdate(Progress...) 此方法在主線程執(zhí)行,用于顯示任務(wù)執(zhí)行的進度。
* onPostExecute(Result) 此方法在主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。
PageTask擴展了AsyncTask,在 doInBackground()方法中讀取網(wǎng)頁內(nèi)容。PageTask的源代碼如下所示:
執(zhí)行PageTask非常簡單,只需要調(diào)用如下代碼。重新運行NetworkActivity,不但可以抓取網(wǎng)頁的內(nèi)容,還可以實時更新讀取的進度。讀者嘗試讀取一個較大的網(wǎng)頁,看看百分比的更新情況。
下載實例: testAsync(VeVB.COm).rar
新聞熱點
疑難解答
圖片精選