編輯:關於Android編程
我曾在《Android開發之異步詳解(一)之Thread+Handler》一文中介紹過通過Thread+Handler實現異步操作。感興趣的朋友可以看一下。
雖然Thread+Handler可以實現更新主線程的UI並實現異步,但Thread+Handler模式需要為每一個任務創建一個新的線程,任務完成後通過Handler實例向UI線程發送消息,完成界面的更新,這種方式對於整個過程的控制比較精細,但也是有缺點的,例如代碼繁瑣,在多個任務同時執行時,不易對線程進行精確的控制。
下面就介紹一下Android中AsyncTask的使用:
從Android 1.5開始系統將AsyncTask引入到android.os包中。AsyncTask,是android提供的輕量級的異步類,可以直接繼承AsyncTask,在類中實現異步操作,並提供接口反饋當前異步執行的程度(可以通過接口實現UI進度更新),最後反饋執行的結果給UI主線程。
AsyncTask的出現使得使用UI線程變得輕巧而簡單。這個類允許執行後台操作,並將操作結果更新到UI線程上而無需操作threads和handlers。
AsyncTask的設計是圍繞線程和Handler一個輔助類,並不構成一個通用線程框架。異步任務最好應采用短作業。如果你需要保持運行很長一段時間的線程,可以使用java.util.concurrent包等提供的ThreadPoolExecutor和FutureTask等各種API來替代。
異步任務被定義運行在後台線程和要發布結果在UI線程上的一個運算。 異步任務被定義為Params,Progress和Result 3通用 類型,和onPreExecute,doInBackground,onProgressUpdate和onPostExecute 4個步驟。
AsyncTask的定義了三種泛型類型 Params,Progress和Result。
public abstract class AsyncTask
Params 啟動任務執行的輸入參數,比如HTTP請求的URL。
Progress 後台任務執行的進度。
Result 後台執行任務最終返回的結果,比如String。
onPreExecute() ,該方法將在執行實際的後台操作前被UI 線程調用。可以在該方法中做一些准備工作,如在界面上顯示一個進度條,或者一些控件的實例化,這個方法可以不用實現。
doInBackground(Params...) ,將在onPreExecute 方法執行後馬上執行,該方法運行在後台線程中。這裡將主要負責執行那些很耗時的後台處理工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
onProgressUpdate(Progress...),在 publishProgress(Progress...)方法被調用後,UI 線程將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
onPostExecute(Result),在doInBackground 執行完成後,onPostExecute方法將被UI 線程調用,後台的計算結果將通過該方法傳遞到UI 線程,並且在界面上展示給用戶。
onCancelled(),在用戶取消線程操作的時候調用。在主線程中調用onCancelled()的時候調用。
AsyncTask允許你在你的用戶界面上執行異步操作。它在一個子線程中執行耗時的操作,然後在UI線程上發布執行結果,而不需要你來處理Thread和Handler。
要使用AsyncTask,你必須繼承AsyncTask和實現doInBackground()回調方法,AsyncTask運行在後台的一個線程池中。若要更新你的UI,你應該實現onPostExecute()方法,它從doInBackground()方法中獲取的結果,並運行在UI線程中,這樣你就可以安全地更新你的UI。你可以在UI線程中調用execute()方法開始你任務。
使用AsyncTask的步驟:
1)創建一個繼承AsyncTask的類
2) 實現AsyncTask中定義的抽象方法doInBackground(Params...),然後根據需要重寫它的其它方法。
3) 調用execute()來開始任務。
看一個例子:
//// 表示從調用位置傳來的參數 // Integer:表示讀取網絡數據的進度 // 從網絡返回的值 class NetTask extends AsyncTask { private String path; private ImageView iv; public NetTask(String path, ImageView iv) { this.path = path; this.iv = iv; } // 主線程中,反饋網絡訪問進度 @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); Log.i(NetUtil, values= + values[0]); } // 主線程中,子線程執行之前執行 @Override protected void onPreExecute() { super.onPreExecute(); } // 子線程 @Override protected Bitmap doInBackground(String... params) { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); // 設置一些連接屬性 conn.setConnectTimeout(5000); conn.setRequestMethod(GET);// POST // 設置http頭信息 //conn.setRequestProperty(Content-type, newValue) if (conn.getResponseCode() == 200) { InputStream is = conn.getInputStream(); return BitmapFactory.decodeStream(is); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } // 在主線程中,網絡返回數據時執行 @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if (result != null) { iv.setImageBitmap(result); } } }
為了正確的使用AsyncTask類,以下是幾條必須遵守的准則:
1) AsyncTask的實例必須在UI 線程中創建。
2) execute方法必須在UI 線程中調用。
3) 不要手動的調用onPreExecute(),onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法,需要在UI線程中實例化這個AsyncTask來調用。
4) 該AsyncTask只能被執行一次,否則多次調用時將會出現異常。
5) doInBackground方法和onPostExecute的參數必須對應,這兩個參數在AsyncTask聲明的泛型參數列表中指定,第一個為doInBackground接受的參數,第二個為顯示進度的參數,第第三個為doInBackground返回和onPostExecute傳入的參數。
AsyncTask實現的原理和適用的優缺點:
AsyncTask,是android提供的輕量級的異步類,可以直接繼承AsyncTask,在類中實現異步操作,並提供接口反饋當前異步執行的程度(可以通過接口實現UI進度更新),最後反饋執行的結果給UI主線程.
使用的優點:
1) 簡單,快捷
2) 過程可控
使用的缺點:
1) 在使用多個異步操作和並需要進行Ui變更時,就變得復雜起來.
Handler異步實現的原理和適用的優缺點:
在Handler 異步實現時,涉及到 Handler,Looper, Message,Thread四個對象,實現異步的流程是主線程啟動Thread(子線程)運行並生成Message-Looper獲取Message並傳遞給HandlerHandler逐個獲取Looper中的Message,並進行UI變更。
使用的優點:
1) 結構清晰,功能定義明確
2) 對於多個後台任務時,簡單,清晰
使用的缺點:
1) 在單個後台異步處理時,顯得代碼過多,結構過於復雜(相對性)
最後需要說明AsyncTask不能完全取代線程,在一些邏輯較為復雜或者需要在後台反復執行的邏輯就可能需要Thread+Handler來實現了。
如果你覺得這篇博文對你有幫助的話,請為這篇博文點個贊吧!也可以關注fengyuzhengfan的博客,收看更多精彩!http://blog.csdn.net/fengyuzhengfan/
之前的幾篇博客,我測試了View事件分發機制中的一些知識點,我們理解事件分發機制的目的就是為了能夠更好了知道View中事件的傳遞過程進而能夠對於滑動沖突有針對性的解決措施
在Android中,很多人會用如下的方法判斷當前網絡是否可用:/** * 獲取當前網絡狀態(是否可用) */ public static boolean isNetwor
Android 實現自定義dialog圓角功能 剛接觸公司的Android項目,客戶畫好了界面,需求如下: 彈出的窗口是要四個圓角,並且標題欄顏色和下
一、前言之前介紹了Android直播視頻中一種視頻源數據采集:攝像頭Camera視頻數據采集分析中介紹了利用Camera的回調機制,獲取攝像頭的每一幀數據,然後進行二次處