在大多数的网络应用程序开发中,都需要从网络中下载图片,并显示图片,如QQ列表头像、微博列表头像等,第一种方法是将列表中的所有图片下载下来在显示,这种方法虽然可行,但在网络环境很差的情况下,下载时间比较长,应用程序容易出现ANR。第二种方式是,在列表显示的时候,每个列表项的头像图片采用异步下载,在头像下载完毕之前,显示默认图片,下载完成后,显示下载的图片头像。
实现该功能的代码如下,定义一个RemoteImageView类继承ImageView,如果下载失败3次,取消下载,使用默认图片显示:
- public class RemoteImageView extends ImageView {
- public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- }
- public RemoteImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- }
- public RemoteImageView(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
- private static int MAX_FAILURES = 3;
- private String m_url;
- private int mFailure;
- private Integer defaultImage;
- public void setDefaultImage(Integer resId) {
- this.defaultImage = resId;
- }
- public void setImage(String url){
- if (url == null || url.equals("")) {
- if (defaultImage != null) {
- setImageResource(defaultImage);
- }
- return;
- }
- if (m_url!= null && m_url.equals(url)) {
- mFailure++;
- if (mFailure > MAX_FAILURES) {
- return;
- }
- }else {
- m_url = url;
- mFailure = 0;
- }
- if (Manager.getInstance().getImageCache().isCached(url)) {
- setImageBitmap(Manager.getInstance().getImageCache().get(url));
- }else {
- new DownLoadImageTask().execute(url);
- }
- }
- /**
- *
- *
- * RemoteImageView.java Create on 2012-8-8 上午11:22:53
- *
- *
- * Params 启动任务执行的输入参数
- * Progress 后台任务执行的百分比
- * Result 后台执行任务最终返回的结果
- * @author wen.yang
- */
- public class DownLoadImageTask extends AsyncTask<String, Integer, String>{
- private static final String TAG = "DownLoadImageTask";
- private InputStream inputStream= null;
- /**
- * onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。
- * 可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化
- */
- @Override
- protected void onPreExecute() {
- // TODO Auto-generated method stub
- if (defaultImage != null) {
- setImageResource(defaultImage);
- }
- }
- /**
- * 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,
- * 后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户
- */
- @Override
- protected void onPostExecute(String result) {
- // TODO Auto-generated method stub
- if (!result.equals(m_url)) {
- return;
- }
- Bitmap bmp = Manager.getInstance().getImageCache().get(result);
- if (bmp != null) {
- RemoteImageView.this.setImageBitmap(bmp);
- }else {
- RemoteImageView.this.setImage(result);
- }
- }
- /**
- * 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要
- * 负责执行那些很耗时的后台处理工作
- */
- @Override
- protected String doInBackground(String... params) {
- String taskUrl = null;
- try {
- taskUrl = params[0];
- BitmapFactory.Options opts = new BitmapFactory.Options();
- //opts.inJustDecodeBounds = true;
- //opts.inSampleSize = ImageHelper.computeSampleSize(opts, -1, 128*128);
- //opts.inJustDecodeBounds = false;
- opts.inInputShareable = true;
- opts.inPurgeable = true; //图片可以被回收
- opts.inPreferredConfig = Bitmap.Config.ALPHA_8;
- long fileSize = HttpDownLoad.getFileSize(taskUrl);
- if (fileSize < 20480) { //0-20k
- opts.inSampleSize =1;
- }else if (fileSize < 51200) { //20-50k
- opts.inSampleSize =2;
- }else if (fileSize < 307200) { //50-300k
- opts.inSampleSize =6;
- }else if (fileSize < 819200) { //300-800k
- opts.inSampleSize =8;
- }else if (fileSize < 1048576) { //800-1024k
- opts.inSampleSize =10;
- }else {
- opts.inSampleSize =14;
- }
- inputStream = new URL(taskUrl).openStream();
- Bitmap bmp =null;
- bmp = BitmapFactory.decodeStream(inputStream, null, opts);
- if (bmp != null) {
- Manager.getInstance().getImageCache().put(taskUrl, bmp);
- }
- } catch (Exception e) {
- Log.e(TAG, "DownLoadImageTask---->doInBackground:"+e.getMessage());
- }finally{
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException e) {
- Log.e(TAG, "DownLoadImageTask---->doInBackground:"+e.getMessage());
- }
- }
- return taskUrl;
- }
- }
- }