Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> AsyncTask的基本用法

AsyncTask的基本用法

編輯:關於Android編程

在開發Android應用時必須遵守單線程模型的原則: Android UI操作並不是線程安全的並且這些操作必須在UI線程中執行。在單線程模型中始終要記住兩條法則:
1. 不要阻塞UI線程
2. 確保只在UI線程中訪問Android UI工具包
當一個程序第一次啟動時,Android會同時啟動一個對應的主線程(Main Thread),主線程主要負責處理與UI相關的事件,如:用戶的按鍵事件,用戶接觸屏幕的事件以及屏幕繪圖事件,並把相關的事件分發到對應的組件進行處理。所以主線程通常又被叫做UI線程。
比如說從網上獲取一個網頁,在一個TextView中將其源代碼顯示出來,這種涉及到網絡操作的程序一般都是需要開一個線程完成網絡訪問,但是在獲得頁面源碼後,是不能直接在網絡操作線程中調用TextView.setText()的.因為其他線程中是不能直接訪問主UI線程成員 。

為了解決這個問題,Android 1.5提供了一個工具類:AsyncTask,它使創建需要與用戶界面交互的長時間運行的任務變得更簡單。相對來說AsyncTask更輕量級一些,適用於簡單的異步處理,不需要借助線程和Handler即可實現。
AsyncTask是抽象類.AsyncTask定義了三種泛型類型 Params,Progress和Result。
  Params 啟動任務執行的輸入參數,比如HTTP請求的URL。
  Progress 後台任務執行的百分比。
  Result 後台執行任務最終返回的結果,比如String。

AsyncTask的執行分為四個步驟,每一步都對應一個回調方法,這些方法不應該由應用程序調用,開發者需要做的就是實現這些方法。
  1) 子類化AsyncTask
  2) 實現AsyncTask中定義的下面一個或幾個方法
   onPreExecute(), 該方法將在執行實際的後台操作前被UI thread調用。可以在該方法中做一些准備工作,如在界面上顯示一個進度條。
   doInBackground(Params...), 將在onPreExecute 方法執行後馬上執行,該方法運行在後台線程中。這裡將主要負責執行那些很耗時的後台計算工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
   onProgressUpdate(Progress...),在publishProgress方法被調用後,UI thread將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
   onPostExecute(Result), 在doInBackground 執行完成後,onPostExecute 方法將被UI thread調用,後台的計算結果將通過該方法傳遞到UI thread.

為了正確的使用AsyncTask類,以下是幾條必須遵守的准則:
  1) Task的實例必須在UI thread中創建
  2) execute方法必須在UI thread中調用
  3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法
  4) 該task只能被執行一次,否則多次調用時將會出現異常
doInBackground方法和onPostExecute的參數必須對應,這兩個參數在AsyncTask聲明的泛型參數列表中指定,第一個為doInBackground接受的參數,第二個為顯示進度的參數,第第三個為doInBackground返回和onPostExecute傳入的參數。

下面是使用AsyncTask下載網絡圖片的例子

public class MainActivity extends Activity {
private Button button;
private ImageView imageview;
private String image_path="http://d.hiphotos.baidu.com/image/w%3D2048/sign=72da8b71d62a60595210e61a1c0c369b/caef76094b36acaf0d08f1447dd98d1000e99c99.jpg";
private ProgressDialog dialog;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog=new ProgressDialog(this);
dialog.setTitle("提示信息");
dialog.setMessage("正在下載,請稍等。。。。");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//進度條的樣式,橫向
dialog.setCancelable(false);//進度條不消失,直到下載完成

button=(Button) this.findViewById(R.id.but);
imageview=(ImageView) this.findViewById(R.id.image);

button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
new MyTask().execute(image_path);
}
});
}

public class MyTask extends AsyncTask{
protected void onPreExecute() {
super.onPreExecute();
dialog.show();
}

protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
dialog.setProgress(values[0]);
}

protected Bitmap doInBackground(String... params) {
// 完成對圖片下載的功能
Bitmap bitmap=null;
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
InputStream inputStream=null;
try {
HttpClient httpClient=new DefaultHttpClient();
HttpGet httpGet=new HttpGet(params[0]);
HttpResponse httpResponse=httpClient.execute(httpGet);
if(httpResponse.getStatusLine().getStatusCode()==200){
inputStream=httpResponse.getEntity().getContent();
//先要獲得文件的總長度
long file_length=httpResponse.getEntity().getContentLength();
int len=0;
byte[] data=new byte[1024];//讀取
int total_length=0;
while((len=inputStream.read(data))!=-1){
total_length += len;
int value=(int) ((total_length / (float) file_length) * 100);
publishProgress(value);//把刻度發布出去
outputStream.write(data, 0, len);//寫入
}
byte[] result=outputStream.toByteArray();//聲明字節數組
bitmap=BitmapFactory.decodeByteArray(result, 0, result. length);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}

protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
imageview.setImageBitmap(result);
}
}
}

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved