文章轉載只能用於非商業性質,且不能帶有虛擬貨幣、積分、註冊等附加條件。轉載須註明出處:http://blog.csdn.net/flowingflying/編程
小例子app
經過簡單的菜單,觸發一個用sleep模擬的任務。Test Async One 1將調用1個AsyncTask任務,咱們在Test Ansync One 2中同時執行兩個task,看看運行的狀況。Test Async Two中互動會更爲複雜,task不只在主線程寫TextView,還開啓一個ProgessDialog。ide
咱們先經過Test Async One 1來學習AsyncTask。首先實現繼承AsyncTask。函數
public class MyLongTask extends AsyncTask<String,Integer,Integer>{
private IReportBack report = null;
private String tag = null;
//【步驟1】:構造函數,IReportBack定義主線程Activity處理task UI操做的回調函數,做爲良好編程風格,無需將Activity對象直接傳遞過來。
public MyLongTask(IReportBack inr, String inTag){
report = inr;
tag = inTag;
}
@Override //【步驟2】:重寫onPreExecute(),這是運行在主線程中(準確來將是運行在建立對象所在線程),進行後臺線程運行先的初始化等處理。因爲運行在主線程,所以可在此進行UI操做。
protected void onPreExecute() {
Log.v(tag, "onPresExecute():" + Utils.getThreadSignature());
report.reportTransient(tag, "In progress ...... "); //調用接口中的UI處理函數。
}
@Override //【步驟4】從程序員的視圖,在worker線程中運行的doInBackground(),經過publishProgress()觸發在主線程運行的的onProgressUpdate(),當中的機制是handler。在此,咱們進行在其餘線程運行時須要觸發的UI處理。
protected void onProgressUpdate(Integer... values) {
Log.v(tag, "onProgressUpdate():" + Utils.getThreadSignature());
Integer i = values[0];
report.reportBack(tag, "Progress: i = " + i);//調用接口中的UI處理函數。
}
@Override //【步驟5】當後臺線程運行完,經過handler將最後結果通知給線程,將在主線程觸發onPostExcute(),在此進行後臺處理結束觸發相關的UI處理。參數result爲doInbackground()的返回值。
protected void onPostExecute(Integer result) {
Log.v(tag, "onPostExecute():" + Utils.getThreadSignature());
report.reportBack(tag, "result: i = " + result);
}
@Override //【步驟3】當調用task.execute()時,將在worker線程中執行doInBackground(),因爲不在主線程中執行,不能再此進行UI操做,若是但願觸發相關的UI操做,經過publishProgress(),利用隱藏的handler在主線程隊列加入message進行處理。主線程處理message,觸發handler的handleMessage(),這些隱藏的步驟經過AsyncTask的封裝,呈現爲觸發onProgressUpdate()。
protected Integer doInBackground(String... params) {
Log.v(tag,"doInBackground():" + Utils.getThreadSignature());
for(int i = 0; i < params.length;i ++){
Utils.sleepForSecs(2); //休眠2秒
publishProgress(i);
}
return params.length;
}
}學習
AsyncTask封裝得很是好,提升task運行前、運行中、運行後的回調函數,在此咱們進行相關的UI處理。這些代碼都放在對AsyncTask繼承類中。處理UI就離不開Activity的View,最直接的方式是將Activity對象經過構造函數傳遞到AsyncTask中,然而在真正的項目開發,這樣作會使一個特定的任務能夠任意調用Activity的功能,二者的界面不清晰,代碼可讀性、可維護性,檢查錯誤方面都不太好。所以,一般會將task涉及到的UI處理放入到接口中。this
public interface IReportBack {
public void reportBack(String tag,String message);
public void reportTransient(String tag,String message);
}.net
咱們將在主線程中建立AsyncTask對象,下面是activity的相關代碼線程
public class MainActivity extends Activity implements IReportBack{
private static TextView tv = null;
… …
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.testOne1){
testMyLongTask();
}
return super.onOptionsItemSelected(item);
}
private void testMyLongTask(){
MyLongTask task = new MyLongTask(this, "TestOne"); //建立AsyncTask對象,經過這個對象,咱們能夠經過調用task.cancel()來中止worker線程,這時會觸發onCanceled(Object)回調函數。
task.execute("Hello","my","friend"); //經過execute() 來觸發後臺線程執行,順序在主線程運行onPreExecute(),而後開線程運行doInBackground()的代碼,doInBackground運行結束後,觸發在主線程運行的onPostExecute()。
}
@Override //接口實現
public void reportBack(String tag, String message) {
tv.append(tag + " : " + message + "\n");
Log.v(tag,message);
}
@Override //接口實現
public void reportTransient(String tag, String message) {
Toast.makeText(this, tag + " : " + message, Toast.LENGTH_SHORT).show();
reportBack(tag,message);
}
} 對象
相關小例子源代碼可在Pro Android學習:AsyncTask小例子中下載。
相關連接: 個人Android開發相關文章