在安卓開發中,咱們常常要進行一些耗時操做,好比數據庫操做,獲取網絡資源,讀取內存文件等等,當咱們在處理這些耗時操做的時候,若是咱們直接在UI主線程進行,那麼可能會致使阻塞UI主線程,使得UI界面卡頓,帶來很很差的用戶體驗,所以安卓也給咱們提供了2個異步操做的類,Handler和AsyncTask。java
今天先講AsyncTask,AsyncTask類是Andorid提供給咱們的一個輕量級異步類,算是一個框架,它對線程之間的通信進行了封裝,而且提供了簡易的編程操做,使得咱們能夠很輕鬆的實現後臺線程和UI主線程之間的通信。android
我寫了一個異步獲取網絡圖片的小例子,先來看實現效果:數據庫
以上是官網對AsyncTask的一些描述,大體意思是:apache
AsyncTask是一個易操做線程使用類,它能夠幫助咱們把後臺線程處理程序的結果發送給UI主線程,使UI線程獲得更新。編程
AsyncTask類提供了3個泛型參數(Params,Progress,Result)和4個執行步驟(下文會具體說起)數組
先來看下3個泛型參數網絡
一、Params:這是一個任務參數,通常咱們會定義成String類型的,例如本例子中要獲取網絡資源的URL地址app
二、Progress:任務執行的刻度,通常咱們會定義成Integer類型框架
三、Result:返回結果類型,例如本例中是對網絡圖片進行獲取,那麼它的返回類型應該是BitMap異步
再來看下4個步驟:
當咱們的類去實現AsyncTask類的時候至少須要實現doInBackground(Params...)方法,這裏做爲學習,我把每個的具體工做任務也說說
它的執行順序是這樣的 onPreExecute-->doInBackground-->onProgressUpdate-->onPostExecute
一、onPreExecute:這是一個預處理方法,在任務開始的時候執行,咱們能夠在這裏進行一些控件的實例化,設置屬性等。(非必須)
二、doInBackground:這是一個任務操做方法,也是最重要的一個方法,全部的耗時操做都應該在這裏執行。(必須)
三、onProgressUpdate:這是一個進度即時更新方法,在這裏咱們能夠即時更新任務滾動條的進度。(非必須,當在doInBackground裏調用publishProgress時觸發)
四、onPostExecute:這是一個任務結果處理方法,在doInBackground裏執行完任務,會將結果通知給這個類,在這類中咱們能夠對UI進行更新操做(非必須)
上面的一、三、4是UI主線程觸發調用的,因此能夠對UI進行更新操做,而第2步是個異步操做,不能在裏面進行UI的更新操做。
關於AsyncTask的調用,其實很是簡單,咱們在AsyncTask類被繼承實現的時候,在主線程直接對其對象調用execute(Params..)方法便可。
好了,文字介紹到此結束,上代碼:
一、佈局文件
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="center" 6 android:orientation="vertical"> 7 8 <ImageView 9 android:id="@+id/imageView" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" /> 12 13 <Button 14 android:id="@+id/bt_download" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:text="下載圖片" /> 18 19 </LinearLayout>
二、AsyncTask的實現類
1 package com.example.asynctasktest; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 8 import org.apache.http.HttpResponse; 9 import org.apache.http.client.ClientProtocolException; 10 import org.apache.http.client.HttpClient; 11 import org.apache.http.client.methods.HttpGet; 12 import org.apache.http.impl.client.DefaultHttpClient; 13 14 import android.app.ProgressDialog; 15 import android.graphics.Bitmap; 16 import android.graphics.BitmapFactory; 17 import android.os.AsyncTask; 18 import android.widget.ImageView; 19 20 public class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> { 21 22 private ImageView imageView; 23 private ProgressDialog progressDialog; 24 25 public MyAsyncTask(ImageView imageView, ProgressDialog progressDialog) { 26 this.imageView = imageView; 27 this.progressDialog = progressDialog; 28 } 29 30 /** 31 * 執行第一步 這裏爲預處理操做,被UI線程所調用(能夠在這裏完成進度條的屬性設置) 32 */ 33 @Override 34 protected void onPreExecute() { 35 super.onPreExecute(); 36 progressDialog.setTitle("當前任務"); 37 progressDialog.setMessage("正在下載圖片,請稍後..."); 38 progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//設置進度條樣式,橫項 39 progressDialog.show(); 40 } 41 42 /** 43 * 執行第二步 這裏爲異步線程,在這裏處理耗時任務操做(好比:下載,讀取文件) 44 * 經過調用publishProgress方法(傳遞即時任務進度)能夠觸發onProgressUpdate的執行 45 */ 46 @Override 47 protected Bitmap doInBackground(String... params) { 48 String path=params[0]; 49 Bitmap bitmap=null; 50 HttpClient httpClient=new DefaultHttpClient(); 51 HttpGet httpGet=new HttpGet(path); 52 InputStream inputStream=null; 53 try { 54 HttpResponse httpResponse=httpClient.execute(httpGet); 55 if(httpResponse.getStatusLine().getStatusCode()==200){ 56 //鏈接成功 57 // HttpEntity entity=httpResponse.getEntity(); 58 // byte[] data=EntityUtils.toByteArray(entity); 59 // bitmap=BitmapFactory.decodeByteArray(data, 0, data.length); 60 61 inputStream=httpResponse.getEntity().getContent(); 62 ByteArrayOutputStream outputStream=new ByteArrayOutputStream(); 63 long fileSize=httpResponse.getEntity().getContentLength();//文件總大小 64 byte[] data=new byte[1024];//每次讀取的大小 65 int len=0;//本次讀取的大小 66 int total=0;//累計讀取的大小 67 while((len=inputStream.read(data))!=-1){ 68 total+=len;//累計讀取的大小 69 int values=(int) ((total/(float)fileSize)*100);//獲得當前任務進行百分比 70 publishProgress(values);//觸發onProgressUpdate更新即時進度 71 outputStream.write(data, 0, len); 72 } 73 byte[] result=outputStream.toByteArray();//轉換爲字節數組 74 bitmap=BitmapFactory.decodeByteArray(result, 0, result.length); 75 } 76 } catch (ClientProtocolException e) { 77 e.printStackTrace(); 78 } catch (IOException e) { 79 e.printStackTrace(); 80 }finally{ 81 if(inputStream!=null){ 82 try { 83 inputStream.close(); 84 } catch (IOException e) { 85 e.printStackTrace(); 86 } 87 } 88 } 89 90 return bitmap; 91 92 } 93 94 /** 95 * 執行第三步 這裏爲實時UI更新操做,被UI線程所調用 在這裏能夠即時更新(如進度條進度) 96 */ 97 @Override 98 protected void onProgressUpdate(Integer... values) { 99 super.onProgressUpdate(values); 100 progressDialog.setProgress(values[0]); 101 } 102 103 /** 104 * 執行第四步 在這裏會返回doInBackground的操做結果,被UI線程調用,更新最後UI結果 105 */ 106 @Override 107 protected void onPostExecute(Bitmap result) { 108 super.onPostExecute(result); 109 progressDialog.dismiss(); 110 imageView.setImageBitmap(result); 111 } 112 113 }
三、主類
1 package com.example.asynctasktest; 2 3 import android.app.ProgressDialog; 4 import android.os.Bundle; 5 import android.support.v7.app.ActionBarActivity; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 import android.widget.ImageView; 10 11 public class MainActivity extends ActionBarActivity { 12 13 private ImageView imageView; 14 private Button bt_download; 15 private ProgressDialog progressDialog;//進度對話框 16 private String path="http://img.pconline.com.cn/images/photoblog/5/3/7/5/5375781/20096/6/1244302842840.jpg";//下載圖片路徑 17 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 23 imageView=(ImageView) findViewById(R.id.imageView); 24 bt_download=(Button) findViewById(R.id.bt_download); 25 progressDialog=new ProgressDialog(this); 26 27 bt_download.setOnClickListener(new OnClickListener() { 28 29 @Override 30 public void onClick(View v) { 31 MyAsyncTask myAsyncTask=new MyAsyncTask(imageView,progressDialog); 32 myAsyncTask.execute(path); 33 } 34 }); 35 36 } 37 38 39 }
代碼到此結束,註釋很詳細應該很好理解。
使用AsyncTask類,如下是幾條必須遵照的準則:
固然AsyncTask類不止這些東西,還有線程池的概念,今天先不講,過幾天連同Handler一塊兒說。
對於簡單的異步操做,掌握這些已經夠了。
項目代碼:http://pan.baidu.com/s/1kTkTgm7
做者:Balla_兔子
出處:http://www.cnblogs.com/lichenwei/本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,往後必有一番做爲!旁邊有「推薦」二字,你就順手把它點了吧,相得準,我分文不收;相不許,你也好回來找我!