萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 安卓開發 >> Android:多線程之AsyncTask

Android:多線程之AsyncTask

 AsyncTask

  AsyncTask,異步任務,可以簡單進行異步操作,並把執行結果發布到UI主線程。AsyncTask是一個抽象類,它的內部其實也是結合了Thread和Handler來實現異步線程操作,但是它形成了一個通用線程框架,更清晰簡單。AsyncTask應該被用於比較簡短的操作(最多幾秒鐘)。如果需要保持長時間運行的線程,可以使用ThreadPooExecutor或者FutureTask,關於這兩個類的內容,以後再介紹,本片博客主要介紹AsyncTask。

  AsyncTask被定義為一個操作,運行在一個後台線程中,其結果被發布在UI線程上。它的異步工作的參數與返回值被泛型的三個參數指定:Params、Progress、Result。AsyncTask將經歷4個步驟:onPreExecute、doInBackground、onProgressUpdate、onPostExecute。下面詳細講解這三個參數與四個步驟:

  三個泛型參數:

  • Params:被發送到執行任務的參數類型。
  • Progress:進度的類型,發送後台的計算進度到UI線程類型。
  • Result:異步任務的返回結果類型。

  一個異步任務將經歷四個階段:

  • onPreExecute():執行在UI線程上調用執行任務之前,一般用於設置任務。
  • doInBackground(Params...):主要是用來執行異步任務的耗時操作,可以在這個方法中通過publishProgress()方法發布進度信息,並在執行完成之後,返回執行結果。
  • onProgreddUpdate(Progress...):在UI線程上接受doInBackground()傳遞過來的進度信息,並在UI線程上展示進度信息,它執行的時機是不確定的。
  • onPostExecute(Result):在UI線程上操作doInBackground()執行的返回值。

  上面介紹的四個步驟的示意圖:

AsyncTask取消任務

  在程序的任何位置,都可以通過cancel(boolean)方法進行取消任務,當取消任務之後,會改變isCancelled()的返回值,使其返回true。之後會調用onCancelled(Object)方法,替代onPostExecute()得到doInBackground()的返回結果。在運行中,可以經常通過isCancelled()方法查看任務是否被取消。

 

AsyncTask的使用規則

  使用AsyncTask必須遵循以下規則:

    %20%20%20%20
  • AsyncTask必須聲明在UI線程上。
  • %20%20%20%20
  • AsyncTask必須在UI線程上實例化。
  • %20%20%20%20
  • 必須通過execute()方法執行任務。
  • %20%20%20%20
  • 不可以直接調用onPreExecute()、onPostExecute(Resut)、doInBackground(Params...)、onProgressUpdate(Progress...)方法。
  • %20%20%20%20
  • 可以設置任務只執行一次,如果企圖再次執行會報錯。

示例

  一個簡單的示例,通過AsyncTask下載一個網絡上的圖片,下載的時候展示一個等待框,並顯示在一個ImageView中。

  實現代碼:

%201%20package%20com.bgxt.datatimepickerdemo;
%202%20
%203%20import%20org.apache.http.HttpEntity;
%204%20import%20org.apache.http.HttpResponse;
%205%20import%20org.apache.http.client.HttpClient;
%206%20import%20org.apache.http.client.methods.HttpGet;
%207%20import%20org.apache.http.impl.client.DefaultHttpClient;
%208%20import%20org.apache.http.util.EntityUtils;
%209%20
10%20import%20android.app.Activity;
11%20import%20android.app.ProgressDialog;
12%20import%20android.graphics.Bitmap;
13%20import%20android.graphics.BitmapFactory;
14%20import%20android.os.AsyncTask;
15%20import%20android.os.Bundle;
16%20import%20android.view.View;
17%20import%20android.widget.Button;
18%20import%20android.widget.ImageView;
19%20
20%20public%20class%20AsyncTaskActivity1%20extends%20Activity%20{
21%20%20%20%20%20private%20Button%20btnDown;
22%20%20%20%20%20private%20ImageView%20ivImage;
23%20%20%20%20%20private%20static%20String%20image_path%20=%20"http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
24     private ProgressDialog dialog;
25 
26     @Override
27     protected void onCreate(Bundle savedInstanceState) {
28         // TODO Auto-generated method stub
29         super.onCreate(savedInstanceState);
30         setContentView(R.layout.asynctask_activity);
31 
32         btnDown = (Button) findViewById(R.id.btnDown);
33         ivImage = (ImageView) findViewById(R.id.ivSinaImage);
34         
35         // 聲明一個等待框以提示用戶等待
36         dialog=new ProgressDialog(this);
37         dialog.setTitle("提示信息");
38         dialog.setMessage("正在下載,請稍後...");
39         
40         btnDown.setOnClickListener(new View.OnClickListener() {
41 
42             @Override
43             public void onClick(View v) {
44                 // 執行一個異步任務,並把圖片地址以參數的形式傳遞進去
45                 new MyTask().execute(image_path);
46             }
47         });
48     }
49 
50     // 以String類型的參數,Void表示沒有進度信息,Bitmap表示異步任務返回一個位圖
51     public class MyTask extends AsyncTask<String, Void, Bitmap> {
52         // 表示任務執行之前的操作
53         @Override
54         protected void onPreExecute() {
55             super.onPreExecute();
56             //顯示等待框
57             dialog.show();
58         }
59 
60         //主要是完成耗時操作
61         @Override
62         protected Bitmap doInBackground(String... params) {
63             HttpClient httpClient=new DefaultHttpClient();
64             HttpGet httpGet=new HttpGet(params[0]);
65             Bitmap bitmap=null;
66             try {
67                 //從網絡上下載圖片
68                 HttpResponse httpResponse =httpClient.execute(httpGet);
69                 if(httpResponse.getStatusLine().getStatusCode()==200){
70                     HttpEntity httpEntity = httpResponse.getEntity();
71                     byte[] data=EntityUtils.toByteArray(httpEntity);
72                     bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);                    
73                 }
74             } catch (Exception e) {
75                 e.printStackTrace();
76             }
77             return bitmap;
78         }
79         
80         //完成更新UI操作
81         @Override
82         protected void onPostExecute(Bitmap result) {
83             // TODO Auto-generated method stub
84             super.onPostExecute(result);
85             //設置ImageView的顯示圖片
86             ivImage.setImageBitmap(result);
87             // 銷毀等待框
88             dialog.dismiss();
89         }
90 
91     }
92 }

  效果展示:

  

  上面的Demo並沒有用到進度的信息,下面再提供一個完整的AsyncTask的Demo,同樣是下載一個圖片,並且展示到一個ImageView中,但是這裡在下載的過程中增加一個進度條對話框,用於展示下載的進度。

  實現代碼:

%20%201%20package%20com.bgxt.datatimepickerdemo;
%20%202%20
%20%203%20import%20java.io.ByteArrayOutputStream;
%20%204%20import%20java.io.InputStream;
%20%205%20
%20%206%20import%20org.apache.http.HttpResponse;
%20%207%20import%20org.apache.http.client.HttpClient;
%20%208%20import%20org.apache.http.client.methods.HttpGet;
%20%209%20import%20org.apache.http.impl.client.DefaultHttpClient;
%2010%20
%2011%20import%20android.app.Activity;
%2012%20import%20android.app.ProgressDialog;
%2013%20import%20android.graphics.Bitmap;
%2014%20import%20android.graphics.BitmapFactory;
%2015%20import%20android.os.AsyncTask;
%2016%20import%20android.os.Bundle;
%2017%20import%20android.view.View;
%2018%20import%20android.widget.Button;
%2019%20import%20android.widget.ImageView;
%2020%20
%2021%20public%20class%20AsyncTaskActivity2%20extends%20Activity%20{
%2022%20%20%20%20%20private%20Button%20btnDown;
%2023%20%20%20%20%20private%20ImageView%20ivImage;
%2024%20%20%20%20%20private%20static%20String%20image_path%20=%20
						
copyright © 萬盛學電腦網 all rights reserved