第十六章 非同步處理之AsyncTask的應用

2022-07-07 08:15:13 字數 3171 閱讀 4573

前言

我們知道android的ui主線程主要負責處理使用者的按鍵事件、使用者的觸屏事件以及螢幕繪圖事件等;既然ui老人家都這麼忙了,我們這些開發者肯定不能不識趣的去添亂阻塞ui執行緒什麼的,否則ui介面萬一停止響應了呢——這不是招罵的節奏麼?!所以我們知道用handler+thread的方法,在子執行緒中處理耗時的任務,任務完成後通過handler通知ui主線程更新ui介面,皆大歡喜有木有。

可是這樣,還是有某些人覺得用handler+thread的**會比較繁瑣,當然這個某些人裡面包括我們偉大的谷歌。所以asynctask(非同步任務)在android 1.5中橫空出世;相對於handler來說,由於比較好的封裝,asynctask顯得更加輕量級一點,適用於簡單的非同步處理;當然使用起來也比較簡潔,果然是谷歌的親兒子!

概述asynctask是乙個抽象類,通常是被繼承的命。asynctask的內部會維持乙個靜態的執行緒池,每個後台任務自然也會被提交到執行緒池中執行,同時也使用handler+thread的機制來呼叫asynctask的各個**方法;**方法是在主線程執行的,所以該幹什麼我們都懂(~ o ~)~zz(趕緊跟ui介面套近乎呀)。

我們知道asynctask是抽象類,我們可以在這裡面看出它支援三種泛型:

1、params:我們的asynctask要開始幹活時,我們給他的輸入的引數的型別,也就是傳遞給後台的引數

3、result:後台執行任務完成,返回的結果的引數型別

如果某個泛型我們不需要指定,我們可以大大方方的指定void,沒事asynctask不會傷心滴。

當然谷歌也幫我們將asynctask的後台任務執行的五種狀態,分別是:1、準備執行,2、正在後台執行,3、進度更新,4、完成後台任務,5、取消任務。每種狀態在asynctask中各有相應的**方法。

1、準備執行:onpreexecute(),在任務開啟時該**方法立即在ui執行緒中被呼叫,同時也是在執行後台耗時操作前被呼叫;通常該方法用於完成一些初始化工作,比如在介面上顯示進度條等。

2、正在後台執行:doinbackground(params...),該**函式由後台執行緒在onpreexecute()方法執行結束後立即呼叫,重寫該方法就是後台執行緒將要完成的耗時任務;由於是由後台執行緒呼叫,所以我們不能直接在這裡更新ui介面,應該使用publishprogress(progress...)觸發**方法onprogressupdate(progress...)進行進度更新;任務計算的結果必須由該函式返回,並被傳遞到onpostexecute()中。

3、進度更新:onprogressupdate(progress...),在doinbackground()中呼叫publishprogress()方法更新任務的執行進度,將會在主線程中觸發該方法,一般用於動態地顯示乙個進度條。

4、完成後台任務:onpostexecute(result),當doinbackground()完成後,系統會自動呼叫onpostexecute()方法,並將doinbackground()的返回值傳遞給該方法。

5、取消任務:oncancelled (),在呼叫asynctask的cancel()方法時呼叫。

案例

public class mainactivity extends actionbaractivity implementsonclicklistener

@override

public voidonclick(view v)

class downtask extends asynctask catch(interruptedexception e)

}string result = "任務已完成";

return result;//將呼叫onpostexecute,並將result傳給該**方法

} @override

protected void onpreexecute()

@override

protected void onpostexecute(string result)

@override

protected void onprogressupdate(integer... values) }}

布局檔案:

android:id="@+id/probar"android:layout_width="match_parent"android:layout_height="wrap_content"style="@android:style/widget.progressbar.horizontal"

/>

android:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textcolor="#000000"android:textsize="20sp"

/>

linearlayout>

**講解:

1、點選button後先例項化乙個asynctask的繼承子類,此時將會建立乙個task。接下來變執行execute(params)方法啟動非同步任務。(同乙個asynctask的例項只能執行execute一次,多次執行會丟擲錯誤)。

3、doinbackground()在後台執行緒執行中,如果需要與ui主線程互動更新進度,可以呼叫publishprogress(values)方法,將會觸發位於ui主線程執行的onprogressupdate(values)的**方法,**中在這裡更新進度條的進度。

4、 當後台任務執行完成後,呼叫onpostexecute(result),傳入的引數是doinbackground()中返回的物件。

注意事項

1、不要在同乙個asynctask例項中多次執行execute(),正確的方法是new乙個asynctask執行一次execute()。

2、耗時任務一定要在doinbackground()中處理,不要在其他**方法中處理耗時任務以免引起ui主線程的阻塞。

3、不要再doinbackground()中更新ui介面,應該通過publishprogress()呼叫**方法更新ui。

5、在不同的android版本中,asynctask多工執行,有些是可以並行有些則是順序執行,不過在高版本android中,可以通過指定引數設定執行緒池執行規則。

第十六章 tcp wrappers

在伺服器向外提供的tcp服務上包裝一層安全檢測機制。外來連線請求首先通過這個安全檢測,獲得安全認證後才可被系統服務接受。hosts.allow hosts.deny 在配置檔案中為各服務分別定義訪問控制規則實現訪問控制,檔案中的規則是即時生效的。配置檔案語法 1 daemon list client...

第十六章 執行緒棧

1 基礎 1 執行緒初始化時,執行緒棧預設1m,所有頁面都是page readwrite屬性,但只為前兩個頁面調撥了物理儲存器,位址低的那個頁面叫防護頁面,為其指定了page guard屬性 2 當執行緒訪問到防護頁面時,由於指定了page guard屬性,系統會得到通知,系統會為防護頁面的下乙個頁...

第十六章 控制迴圈

第十六章 控制迴圈 16.1 選擇迴圈的種類 1.在大多數語言中,你只能用到少數幾種迴圈 1 計數迴圈 執行次數一定。2 連續求值的迴圈 預先並不知道將要執行多少次,它會在每次迭代時檢查是否應該結束。3 無限迴圈 一旦啟動就一直執行下去。4 迭代器迴圈 對容器類裡面的每個元素執行一次操作。2.什麼時...