編輯:Android開發實例
AsyncTask (API level 3,所以幾乎所有目前在市面上流通的 Android 版本皆可使用)
是除 Thread 外的另一種選擇,Android 團隊鼓勵主執行緒(UI thread) 專注於操作 & 畫面的流暢呈現,
其余工作 (如網絡資料傳輸、檔案/磁碟/資料存取) 最好都在背景執行;
Thread 通常要搭配 Handler 使用,而 AsyncTask 用意在簡化背景執行 thread 程序碼的撰寫。
如果您預期要執行的工作能在幾秒內完成,就可以選擇使用 AsyncTask,若執行的時間很長,
Android 則強烈建議采用 Executor, ThreadPoolExecutor and FutureTask。
要使用 AsyncTask,必定要建立一個繼承自 AsyncTask 的子類別,並傳入 3 項資料:
若您沒有參數要傳入,則填入 Void (注意 V 為大寫)。
AsyncTask 的運作有 4 個階段:
除了 doInBackground,其他 3 個 method 都是在 UI thread 呼叫
炫酷進度條實例
我們以一個實例來說明,“點擊按鈕開始下載QQAndroid安裝包,然後顯示一個對話框來反饋下載進度”。我們先初始化一個對話框,由於要顯示進度,我們用Github上面一個能夠顯示百分比的進度條 NumberProgressbar,啟動任務的按鈕我們使用 circlebutton,一個有酷炫動畫的按鈕,Github上面有很多非常好的開源項目,當然炫酷的控件是其中一部分了,後面有機會,會去學習一些比較流行的控件它們的實現原理,今天就暫且拿來主義了~~。
1.先初始化進度條提示對話框。
builder = new AlertDialog.Builder( MainActivity.this); LayoutInflater inflater = LayoutInflater.from(MainActivity.this); mDialogView = inflater.inflate(R.layout.progress_dialog_layout, null); mNumberProgressBar = (NumberProgressBar)mDialogView.findViewById(R.id.number_progress_bar); builder.setView(mDialogView); mDialog = builder.create();
2.設置按鈕點擊事件。
findViewById(R.id.circle_btn).setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { dismissDialog(); mNumberProgressBar.setProgress(0); myTask = new MyAsyncTask(); myTask.execute(qqDownloadUrl); } });
3.DownloadAsyncTask實現,有點長。
private class DownloadAsyncTask extends AsyncTask<String , Integer, String> { @Override protected void onPreExecute() { super.onPreExecute(); mDialog.show(); } @Override protected void onPostExecute(String aVoid) { super.onPostExecute(aVoid); dismissDialog(); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); mNumberProgressBar.setProgress(values[0]); } @Override protected void onCancelled(String aVoid) { super.onCancelled(aVoid); dismissDialog(); } @Override protected void onCancelled() { super.onCancelled(); dismissDialog(); } @Override protected String doInBackground(String... params) { String urlStr = params[0]; FileOutputStream output = null; try { URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); String qqApkFile = "qqApkFile"; File file = new File(Environment.getExternalStorageDirectory() + "/" + qqApkFile); if (file.exists()) { file.delete(); } file.createNewFile(); InputStream input = connection.getInputStream(); output = new FileOutputStream(file); int total = connection.getContentLength(); if (total <= 0) { return null; } int plus = 0; int totalRead = 0; byte[] buffer = new byte[4*1024]; while((plus = input.read(buffer)) != -1){ output.write(buffer); totalRead += plus; publishProgress(totalRead * 100 / total); if (isCancelled()) { break; } } output.flush(); } catch (MalformedURLException e) { e.printStackTrace(); if (output != null) { try { output.close(); } catch (IOException e2) { e2.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); if (output != null) { try { output.close(); } catch (IOException e2) { e2.printStackTrace(); } } } finally { if (output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } }
這樣一個簡單的下載文件文件就基本實現了,到目前為止談不上技巧,但是現在我們有一個問題,就是如果我們的Activity正在後台執行一個任務,可能耗時較長,那用戶可能會點擊返回退出Activity或者退出App,那麼後台任務不會立即退出,如果AsyncTask內部有Activity中成員變量的引用,還會造成Activity的回收延時,造成一段時間內的內存洩露,所以我們需要加上下面的第四步處理。
4.onPause中判斷應用是否要退出,從而決定是否取消AsyncTask執行。
@Override protected void onPause() { super.onPause(); if (myTask != null && isFinishing()) { myTask.cancel(false); } }
這樣我們的異步任務就會在Activity退出時,也隨之取消任務執行,順利被系統銷毀回收,第四步很多時候會被遺漏,而且一般也不會有什麼致命的問題,但是一旦出問題了,就很難排查,所以遵循編碼規范還是有必要的。
前一節中將了貪吃蛇Snake游戲的暫停/繼續、穿牆和全屏功能的實現,本文繼續分
本文實例講述了Android中Market的Loading效果實現方法。分享給大家供大家參考。具體如下: 在Android中,要實現Loading效果,一般情況下
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
在應用程序中有些時候,如果想詢問用戶采取決定是或否所采取的特殊動作的回應,由停在原來的活動而不改變屏幕,可以使用警告對話框(Alert Dialog)。要使用一個警告對話