Introduction
Android應用程式中常會遇到需要耗時執行的時候(下載音樂),因此我們會將這部分的工作安排在背景後面工作,以免造成使用者還須等待下載工作完成後才能繼續執行其他操作,一般作法都會使用Thread、 Handler。
Android為了降低開發上的難度,提供了AsyncTask供開發者方便使用。 AsyncTask就是一個封裝過的後台任務類,稱為"異步任務"。AsyncTask 讓我們可以在UI thread(使用者介面執行緒,也就是你手機應用程式畫面所看到的)中執行非同步工作。它在worker thread中執行需耗時的工作,然後將結果傳回使用介面緒,省掉我們處裡
Thread、 Handler的麻煩。
Application
常見的有上傳下載圖片音樂,當我們在一邊瀏覽音樂目錄,有一邊下載想要音樂時。
解決Intent回傳於onActivityResult方法中無法顯示提醒視窗或等待視窗(如 ProcessDialog等)。
Overview
建立一個內部類繼承AsyncTask 類別,宣告子類別時指定所使用的三個泛型參數的類別,
Params,Progress和Result。
AsyncTask<Params, Progress, Result>,實作時定義參數型態,
Params 啟動任務執行的輸入參數,如HTTP請求的URL。
Progress 後台任務執行的百分比。
Result 後台執行任務最終返回的結果,如String。
例如AsyncTask<
Integer , Integer , String >
Params為Integer ; Params為Integer ;
Result 為String
AsyncTask<Integer, Integer, String>
第一個參數對應呼叫execute()和doInBackground()的參數,不故定數目的參數,可以是陣列。
第二個參數對應呼叫publishProgress()和onProgressUpdate()的參數,
不故定數目的參數,可以是陣列 。
第三個參數對應doInBackground()的回傳值和onPostExecute()的呼叫參數。
生命週期:
1. execute() :於UI Tread啟動任務
2. onPreExecute() : 任務開始
3. doInBackground() : 在背景執行緒池,執行主要的背景工作,自動在worker thread中執行。可隨時呼叫 publishProgress() 來執行介面緒的 onProgressUpdate()更新介面進度。doInBackground() 的傳回值會傳給 onPostExecute()。
4. onProgressUpdate() :獲取資料即時在介面上更新
5. onPostExecute() : 任務結束
onPreExecute(), onPostExecute(), 和 onProgressUpdate() 都在介面緒執行(不直接呼叫也不可手動呼叫)。
PS:記得處理工作緒的意外重新啟動,例如使用者旋轉螢幕等。
http://changxianli6121.blog.163.com/blog/static/56392130201042712956597/
http://neurosoft.blogspot.com/2011/11/android-threads-handlers-and-asynctask.html
http://developer.android.com/reference/android/os/AsyncTask.html
http://zjf1428.iteye.com/blog/919066
以下code為一開始跳出等待視窗,等待進度bar完成後,等待視窗便消失!
--------------------------------------------------------------------------------------------------------
public class AsyncTask1Activity extends Activity {
/** Called when the activity is first created. */
private ProgressBar pBar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pBar = (ProgressBar) findViewById(R.id.progress_bar);
//AsyncTask.execute()要在主線程調用
new AsyncLoader().execute(0);
}
//AsyncTask
// 設置三種參數分別是<Integer,Integer,String> ,對應著
// doInBackground(Params),onProgressUpdate(Progress),onPostExecute(Result)參數
class AsyncLoader extends
AsyncTask<Integer, Integer, String>{
private ProgressDialog pdg = null;
@Override
protected String
doInBackground(Integer...integers) {
// TODO Auto-generated method stub
Log.d("TAG", "doInBackground()");
for (int i=integers[0]; i <= 100;i+=10) {
publishProgress(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void
onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//任務執行前
Log.d("TAG", "onPreExecute");
pdg = ProgressDialog.show(AsyncTask1Activity.this,"please wait...","Android accessing",true);
}
@Override
protected void
onProgressUpdate(Integer... progress) {
// TODO Auto-generated method stub
super.onProgressUpdate(progress);
//任務執行中UI上進度更新
Log.d("TAG", "onProgressUpdate");
pBar.setProgress(
progress[0]);
}
@Override
protected void
onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//任務執行後
Log.d("TAG", "onPostExecute");
pdg.dismiss();
}
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
Log.d("TAG", "onCancelled");
}
}
}