- AsyncTask实现的原理,和适用的优缺点
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
以下部分是学习代码:
UI:
1 <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context=".MainActivity" > 10 11 <ImageView 12 android:id="@+id/imageView1" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:maxWidth="750dp" 16 android:maxHeight="400dp" 17 android:adjustViewBounds="true" 18 /> 19 20 <Button 21 android:id="@+id/button1" 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content" 24 android:layout_alignParentBottom="true" 25 android:layout_centerHorizontal="true" 26 android:layout_marginBottom="68dp" 27 android:text="下载网络图片" /> 28 29 30 </RelativeLayout>
Activity:
1 package com.example.android_asynctask_downloadimage; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 7 import org.apache.http.HttpResponse; 8 import org.apache.http.client.HttpClient; 9 import org.apache.http.client.methods.HttpGet; 10 import org.apache.http.impl.client.DefaultHttpClient; 11 12 import android.app.Activity; 13 import android.app.ProgressDialog; 14 import android.graphics.Bitmap; 15 import android.graphics.BitmapFactory; 16 import android.os.AsyncTask; 17 import android.os.Bundle; 18 import android.view.Menu; 19 import android.view.View; 20 import android.widget.Button; 21 import android.widget.ImageView; 22 23 /** 24 * @author xiaowu 25 * NOTE:异步任务AsyncTask 26 */ 27 public class MainActivity extends Activity { 28 private Button button ; 29 private Button button2 ; 30 private ImageView imageView ; 31 private final String IMAGE_PATH ="http://e.hiphotos.baidu.com/zhidao/pic/item/c2fdfc039245d68858f1c69fa5c27d1ed21b241d.jpg"; 32 private ProgressDialog progressDialog ; 33 @Override 34 protected void onCreate(Bundle savedInstanceState) { 35 super.onCreate(savedInstanceState); 36 setContentView(R.layout.activity_main); 37 button = (Button) this.findViewById(R.id.button1); 38 progressDialog = new ProgressDialog(MainActivity.this); 39 progressDialog.setTitle("提示"); 40 // progressDialog.setCancelable(false); 41 progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 42 progressDialog.setMessage("正在下载图片,请耐心等待..."); 43 44 imageView = (ImageView) this.findViewById(R.id.imageView1); 45 button.setOnClickListener(new View.OnClickListener() { 46 @Override 47 public void onClick(View v) { 48 // TODO Auto-generated method stub 49 new MyTask().execute(IMAGE_PATH); 50 } 51 }); 52 53 } 54 /** 55 * @author xiaowu 56 * 异步任务AsyncTask,执行网络下载图片 57 * AsyncTask<String, Integer, byte[]> 如果异步任务不需要参数传递,可以直接将参数设置为Void 58 * params: 59 * String:(网络图片的)路径 60 * Integer: 进度单位,刻度类型 61 * byte[]:异步任务执行的返回结果 62 * 异步任务有4个步骤: 63 * 1、onPreExecute(); 在异步任务执行之前执行,用来构建一个异步任务,如显示一个进度条给用户看 64 * 2、doInBackground(Params...); 异步任务必须实现的方法,具体的异步任务所做的事情 65 * 3、onProgressUpdate(Progress...); 66 * 4、onPostExecute(Result); 67 */ 68 public class MyTask extends AsyncTask<String, Integer, byte[]>{ 69 //在异步任务执行之前执行,用来构建一个异步任务,如显示一个进度条给用户看 70 @Override 71 protected void onPreExecute() { 72 // TODO Auto-generated method stub 73 super.onPreExecute(); 74 //展示进度条对话框 75 progressDialog.show(); 76 } 77 //异步任务必须实现的方法,具体的异步任务所做的事情。并将结果返回值最后一个步骤。 78 @Override 79 protected byte[] doInBackground(String... params) { 80 // TODO Auto-generated method stub 81 // 82 HttpClient httpClient = new DefaultHttpClient(); 83 HttpGet httpGet = new HttpGet(params[0]); 84 InputStream inputStream = null; 85 byte[] result = null; //图片的所有内容 86 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 87 try { 88 //发起get请求,并获取反馈 89 HttpResponse httpResponse = httpClient.execute(httpGet); 90 long file_length = httpResponse.getEntity().getContentLength(); //文件实际总长度 91 int total_length = 0 ; 92 byte[] data = new byte[1024]; 93 int len = 0 ; 94 if (httpResponse.getStatusLine().getStatusCode()==200) { 95 // result = EntityUtils.toByteArray(httpResponse.getEntity()); 96 //读取返回内容(内容是以流的形式返回) 97 inputStream = httpResponse.getEntity().getContent(); 98 //更新进度条并读取数据 99 while ((len = inputStream.read(data)) != -1) { 100 total_length +=len ; 101 int progress_value = (int) ((total_length/ (float) file_length)*100); 102 //通过publishProgress()方法发布进度值到onProgressUpdate 103 publishProgress(progress_value); //发布刻度单位 104 byteArrayOutputStream.write(data, 0, len); 105 } 106 } 107 result = byteArrayOutputStream.toByteArray(); 108 }catch (IOException e) { 109 // TODO Auto-generated catch block 110 e.printStackTrace(); 111 }finally{ 112 //关连接 113 httpClient.getConnectionManager().shutdown(); 114 } 115 116 return result; 117 } 118 //更新UI展示信息:如进度条的变动 119 @Override 120 protected void onProgressUpdate(Integer... values) { 121 // TODO Auto-generated method stub 122 super.onProgressUpdate(values); 123 progressDialog.setProgress(values[0]); 124 } 125 //将doInBackground的执行结果展示到UI 126 @Override 127 protected void onPostExecute(byte[] result) { 128 // TODO Auto-generated method stub 129 super.onPostExecute(result); 130 Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length); 131 imageView.setImageBitmap(bitmap); 132 progressDialog.dismiss(); 133 } 134 135 } 136 @Override 137 public boolean onCreateOptionsMenu(Menu menu) { 138 // Inflate the menu; this adds items to the action bar if it is present. 139 getMenuInflater().inflate(R.menu.main, menu); 140 return true; 141 } 142 143 }