AsyncTask解決Android UI堵塞問題平時我們在開發Android程式時遇 到較耗時任務的處理,如I/O訪問的資料庫操作、網 絡訪問等情況時造成UI假死等問題,通過AsyncTask可以很好的解決這個問題,就今天以在Android中執行 Downloader.downloadFile(url),可能會堵塞整個介面。顯然這會影響使用者體驗,我們如何解決這個問題呢?
方 法一、
建立一個新的線程執行我們的任務,使用Thread類,在 run(){}中寫入任務代碼,比如:查 看
打 印?01.new Thread(new Runnable() {02. 03.public void run() {04. 05. Downloader.downloadFile(url);06. 07.}08. 09.}).start();
但使用Thread會產生一些意想不到的問題,需要程式員用更多的代碼手動的維護它。
方法二: Android SDK為我們提供了一個背景工作的處理工具AsyncTask。AsyncTask就是一個封裝過的背景工作類顧名思義就是非同步任務,方便我們維 護,Android開發網提示這樣的好處可以解決一些安全執行緒問題,AsyncTask直接繼承於Object類,位置為android.os.AsyncTask。要 使用AsyncTask工作我們要提供三個泛型參數,並重載四個方法(至少重載一個)。
三個泛型:
Param ,任務執行器需要的資料類型
Progress 後台計算中使用的進度單位元據類型
Result 後台計算返回結果的資料類型
有些參數是可以設定為不使用的,只要傳遞為Void型即可,比如AsyncTask
四個步驟:
onPreExecute(),執行預先處理,它運行於UI線程,可以為背景工作做一些準備工作,比如繪製一個進度條控制項。
doInBackground(Params...),後台進程執行的具體計算在這裡實 現,doInBackground(Params...)是AsyncTask的關鍵,此方法必須重載。在這個方法內可以使用 publishProgress(Progress...)改變當前的進度值。
onProgressUpdate(Progress...),運行於UI線程。如果在doInBackground(Params...) 中使用了publishProgress(Progress...),就會觸發這個方法。在這裡可以對進度條控制項根據進度值做出具體的響應。
onPostExecute(Result),運行於UI線程,可以對背景工作的結果做出處理,結果就是 doInBackground(Params...)的傳回值。此方法也要經常重載,如果Result為null表明背景工作沒有完成(被取消或者出現異 常)。
AsyncTask執行個體代碼:查 看
打 印?01.private class DownloadFilesTask extends AsyncTask {02. 03. protected Long doInBackground(URL... urls) {04. 05. int count = urls.length;06. 07. long totalSize = 0;08. 09. for (int i = 0; i < count; i++) {10. 11. totalSize += Downloader.downloadFile(urls[i]);12. 13. publishProgress((int) ((i / (float) count) * 100)); //下載進度計算14. 15. }16. 17. return totalSize;18. 19. }20. 21. protected void onProgressUpdate(Integer... progress) {22. 23. setProgressPercent(progress[0]); //更新進度顯示24. 25. }26. 27. protected void onPostExecute(Long result) {28. 29. showDialog("Android123下載測試 " + result + " bytes");30. 31. }32. 33. }34. 35. 在Activity中我們這樣使用它:36. 37. try{38. 39. new DownloadFilesTask ().execute(url);40. 41. }catch (Exception e) {42. 43. Log.e("error", e.toString());44. 45. }