編輯:關於Android編程
本篇就說說AsyncTask的異步實現。
1、什麼時候使用 AsnyncTask
在上一篇文章已經說了,主線程主要負責控制UI頁面的顯示、更新、交互等。 為了有更好的用戶體驗,UI線程中的操作要求越短越好。
我們把耗時的操作(例如網絡請求、數據庫操作、復雜計算)放到單獨的子線程中操作,以避免主線程的阻塞。但是在子線程中不能更新UI界面,這時候需要使用handler。
但如果耗時的操作太多,那麼我們需要開啟太多的子線程,這就會給系統帶來巨大的負擔,隨之也會帶來性能方面的問題。在這種情況下我們就可以考慮使用類AsyncTask來異步執行任務,不需要子線程和handler,就可以完成異步操作和刷新UI。
不要隨意使用AsyncTask,除非你必須要與UI線程交互.默認情況下使用Thread即可,要注意需要將線程優先級調低.AsyncTask適合處理短時間的操作,長時間的操作,比如下載一個很大的視頻,這就需要你使用自己的線程來下載,不管是斷點下載還是其它的.
2、AsnyncTask原理
AsyncTask主要有二個部分:一個是與主線程的交互,另一個就是線程的管理調度。雖然可能多個AsyncTask的子類的實例,但是AsyncTask的內部Handler和ThreadPoolExecutor都是進程范圍內共享的,其都是static的,也即屬於類的,類的屬性的作用范圍是CLASSPATH,因為一個進程一個VM,所以是AsyncTask控制著進程范圍內所有的子類實例。
AsyncTask內部會創建一個進程作用域的線程池來管理要運行的任務,也就就是說當你調用了AsyncTask的execute()方法後,AsyncTask會把任務交給線程池,由線程池來管理創建Thread和運行Therad。
3、AsyncTask介紹
Android的AsyncTask比Handler更輕量級一些(只是代碼上輕量一些,而實際上要比handler更耗資源),適用於簡單的異步處理。
Android之所以有Handler和AsyncTask,都是為了不阻塞主線程(UI線程),因為UI的更新只能在主線程中完成,因此異步處理是不可避免的。
AsyncTask:對線程間的通訊做了包裝,是後台線程和UI線程可以簡易通訊:後台線程執行異步任務,將result告知UI線程。
使用AsyncTask分為兩步:
① 繼承AsyncTask類實現自己的類
public abstract class AsyncTask {
Params: 輸入參數,對應excute()方法中傳遞的參數。如果不需要傳遞參數,則直接設為void即可。
Progress:後台任務執行的百分比
Result:返回值類型,和doInBackground()方法的返回值類型保持一致。
②復寫方法
最少要重寫以下這兩個方法:
doInBackground(Params…)
在子線程(其他方法都在主線程執行)中執行比較耗時的操作,不能更新UI,可以在該方法中調用publishProgress(Progress…)來更新任務的進度。Progress方法是AsycTask中一個final方法只能調用不能重寫。
onPostExecute(Result)
使用在doInBackground 得到的結果處理操作UI, 在主線程執行,任務執行的結果作為此方法的參數返回。
有時根據需求還要實現以下三個方法:
onProgressUpdate(Progress…)
可以使用進度條增加用戶體驗度。 此方法在主線程執行,用於顯示任務執行的進度。
onPreExecute()
這裡是最終用戶調用Excute時的接口,當任務執行之前開始調用此方法,可以在這裡顯示進度對話框。
onCancelled()
用戶調用取消時,要做的操作
4、AsyncTask示例
按照上面的步驟定義自己的異步類:
public class MyTask extends AsyncTask {
//執行的第一個方法用於在執行後台任務前做一些UI操作
@Override
protected void onPreExecute() {
}
//第二個執行方法,在onPreExecute()後執行,用於後台任務,不可在此方法內修改UI
@Override
protected String doInBackground(String... params) {
//處理耗時操作
return "後台任務執行完畢";
}
/*這個函數在doInBackground調用publishProgress(int i)時觸發,雖然調用時只有一個參數
但是這裡取到的是一個數組,所以要用progesss[0]來取值
第n個參數就用progress[n]來取值 */
@Override
protected void onProgressUpdate(Integer... progresses) {
//"loading..." + progresses[0] + "%"
super.onProgressUpdate(progress);
}
/*doInBackground返回時觸發,換句話說,就是doInBackground執行完後觸發
這裡的result就是上面doInBackground執行後的返回值,所以這裡是"後台任務執行完畢" */
@Override
protected void onPostExecute(String result) {
}
//onCancelled方法用於在取消執行中的任務時更改UI
@Override
protected void onCancelled() {
}
}
在主線程申明該類的對象,調用對象的execute()函數開始執行。
MyTask t= new MyTask();
t.execute();//這裡沒有參數
5、使用AsyncTask需要注意的地方
AsnycTask內部的Handler需要和主線程交互,所以AsyncTask的實例必須在UI線程中創建
AsyncTaskResult的doInBackground(mParams)方法執行異步任務運行在子線程中,其他方法運行在主線程中,可以操作UI組件。
一個AsyncTask任務只能被執行一次。
運行中可以隨時調用AsnycTask對象的cancel(boolean)方法取消任務,如果成功,調用isCancelled()會返回true,並且不會執行 onPostExecute() 方法了,而是執行 onCancelled() 方法。
對於想要立即開始執行的異步任務,要麼直接使用Thread,要麼單獨創建線程池提供給AsyncTask。默認的AsyncTask不一定會立即執行你的任務,除非你提供給他一個單獨的線程池。如果不與主線程交互,直接創建一個Thread就可以了。
首先來看一下我實現的效果圖: 從”我的關注”開始,每一個條目都是一個自定義組合控件.下面,我來講解一下具體實現步驟: 一.根據
一:新建HelloEditText工程創建設置如下:Project name:HelloEditText Build Target :android 2.2 Applic
1、前言jni是java調用原生語言來進行開發的一座橋梁,原生語言一般是指c,c++語言,即jni機制可以讓java語言調用c,c++語言,也可以讓c,c++語言調用ja
Android 軟鍵盤自動彈出與關閉在我們寫修改信息或者搜索,修改密碼等界面的時候,用戶進入這個界面的主要目的就是輸入修改/查找 某些信息,為了用戶體驗應該自動彈出軟鍵盤