Android中使用Handler和异步任务(AsyncTack)来为UI线程执行费时操作
出于性能優化的考慮,Android的UI線程不是線程安全的。這致使我們不能在Android的UI線程中執行一些費時的操作,如下載、刷新等。Android中只允許UI線程對Activity中的UI組件進行修改。
不過我們可以新建一條線程來代替UI線程執行這一操作,在Android中可以借助于Handler的消息傳遞機制來實現。
Handler類的兩個主要作用:
1)在新啟的線程中發送消息;
2)在主線程中獲取和處理消息。
我們利用Handler的這兩個作用,可以先在主線程中新建一條新的輔助線程,并且在這條新的線程中執行發送消息。這個消息就是我們通知系統,說現在需要更新UI界面了。如下:
new Timer().schedule(new TimerTask() {@Overridepublic void run() {handler.sendEmptyMessage(0x1233);}}, 0, 1000);
上面的代碼重寫了Handler的sendMessage(Message msg),不過在這里使用的是sendEmptyMessage(int what),因為這里只是通知主線程更新界面,沒有過多的其他操作,所以只需要發送一條空的消息即可。若是更新的內容比較多或是一些其它的限制不能只發送一條空消息就能解決,那就應該發送一些有實質內容的東西,而這咱消息內容是Object的類型。對于Object這種類型的消息,是一個很寬泛的類型,它能裝載的內容太多了。這個時候需要使用sendMessage(Message msg)。廢話有點多,見諒。。。
那么當主線程拿到這條消息時,就會對其進行處理:
Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == 0x1233) {((ImageView) findViewById(R.id.imageView1)).setImageResource(imageId[(currentImg++) % imageId.length]);}}};以上就是簡單地使用Handler來處理UI線程不安全問題。具體的代碼實現還有不發送空消息來更新界面的代碼以及AsyncTask的代碼,我會在下面的給出連接。
-------------------------------------------------------------------------------------------------------------------------------------------------------
下面我們再來看看異步任務(AsyncTask)的簡單用例。
使用AsyncTask需要有如下三個步驟:
1)創建AsyncTask的子類,并為其三個泛型參數指定類型。如果某個泛型參數不需要指定類型,則用void代替;
2)根據需要,實現AsyncTask的以下幾個方法:
Ⅰ.doInBackground(Params...)這個方法,就是AsyncTask子類執行異步任務內容的方法;
Ⅱ.onProgressUpdate(Progress...)這個方法,會在執行完上一個方法后,被調用;
Ⅲ.onPreExecute()這個方法會在我們執行費時操作之前被調用,用于處理一些準備工作,如初始進度條什么的;
Ⅳ.onPostExecute()當doInBackground()執行完成之后,系統會自動調用該方法,并把doInBackground()執行的結果返回給該方法。
3)最后一步就是,我們在主線程中調用AsyncTask實例的execute(Params ... param)方法,表示開始執行費時操作。
如下代碼:
class DownTask extends AsyncTask<URL, Integer, String> {// 可變長的輸入參數,與AsyncTask.exucute()對應ProgressDialog pdialog;// 定義記錄已經讀取行的數量int hasRead = 0;Context mContext;public DownTask(Context ctx) {mContext = ctx;}@Overrideprotected void onPreExecute() {pdialog = new ProgressDialog(mContext);pdialog.setTitle("任務正在執行中");pdialog.setMessage("任務正在執行中,敬請等待...");// 設置對話框不能用“取消”按鈕關閉pdialog.setCancelable(false);// 設置該進度條的最大進度值pdialog.setMax(202);// 設置對話框的進度條風格pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);// 設置對話框的進度條是否顯示進度pdialog.setIndeterminate(false);pdialog.show();}@Overrideprotected String doInBackground(URL... params) {StringBuilder sb = new StringBuilder();try {URLConnection conn = params[0].openConnection();// 打開conn連接對應的輸入流,并將它包裝成BufferedReaderBufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));String line = null;while ((line = br.readLine()) != null) {sb.append(line + "\n");hasRead++;publishProgress(hasRead);}return sb.toString();} catch (Exception e) {e.printStackTrace();}return null;}@Overrideprotected void onProgressUpdate(Integer... values) {// 更新進度show.setText("已經讀取了【" + values[0] + "】行!");pdialog.setProgress(values[0]);}@Overrideprotected void onPostExecute(String result) {// 返回HTML頁面的內容show.setText(result);pdialog.dismiss();}}
關于Handler和AsyncTack的使用就簡單介紹到這里。 本篇博客主要參考資料是《瘋狂Android講義》第3章內容。
----------------------------------------------------------點擊進行源碼的下載連接 -----------------------------------------------------------
總結
以上是生活随笔為你收集整理的Android中使用Handler和异步任务(AsyncTack)来为UI线程执行费时操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在ListView中使用BaseAdap
- 下一篇: Android Wifi开发之WifiC