android ListView 异步加载图片

异步加载图片的目的只有一个:让用户体验更好

因为异步加载不利用主线程(UI线程)

一、源码结构:

android ListView 异步加载图片

二、异步图片加载器(实现异步加载的核心)

 

Java代码 android ListView 异步加载图片
  1. package com.ning.lazytest;   
  2.   
  3. import java.io.IOException;   
  4. import java.io.InputStream;   
  5. import java.lang.ref.SoftReference;   
  6. import java.net.MalformedURLException;   
  7. import java.net.URL;   
  8. import java.util.HashMap;   
  9.   
  10. import android.graphics.drawable.Drawable;   
  11. import android.os.Handler;   
  12. import android.os.Message;   
  13.   
  14. public class AsyncImageLoader {   
  15.     private HashMap<String, SoftReference<Drawable>> imageCache;   
  16.          
  17.     public AsyncImageLoader() {   
  18.      imageCache = new HashMap<String, SoftReference<Drawable>>();   
  19.     }   
  20.     
  21.     public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {   
  22.         if (imageCache.containsKey(imageUrl)) {   
  23.             SoftReference<Drawable> softReference = imageCache.get(imageUrl);   
  24.             Drawable drawable = softReference.get();   
  25.             if (drawable != null) {   
  26.                 return drawable;   
  27.             }   
  28.         }   
  29.         final Handler handler = new Handler() {   
  30.             public void handleMessage(Message message) {   
  31.                 imageCallback.imageLoaded((Drawable) message.obj, imageUrl);   
  32.             }   
  33.         };   
  34.         new Thread() {   
  35.             @Override  
  36.             public void run() {   
  37.                 Drawable drawable = loadImageFromUrl(imageUrl);   
  38.                 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));   
  39.                 Message message = handler.obtainMessage(0, drawable);   
  40.                 handler.sendMessage(message);   
  41.             }   
  42.         }.start();   
  43.         return null;   
  44.     }   
  45.     
  46.     public static Drawable loadImageFromUrl(String url) {   
  47.         URL m;   
  48.         InputStream i = null;   
  49.         try {   
  50.             m = new URL(url);   
  51.             i = (InputStream) m.getContent();   
  52.         } catch (MalformedURLException e1) {   
  53.             e1.printStackTrace();   
  54.         } catch (IOException e) {   
  55.             e.printStackTrace();   
  56.         }   
  57.         Drawable d = Drawable.createFromStream(i, "src");   
  58.         return d;   
  59.     }   
  60.     
  61.     public interface ImageCallback {   
  62.         public void imageLoaded(Drawable imageDrawable, String imageUrl);   
  63.     }   
  64. }  
package com.ning.lazytest; import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; public class AsyncImageLoader { private HashMap<String, SoftReference<Drawable>> imageCache; public AsyncImageLoader() { imageCache = new HashMap<String, SoftReference<Drawable>>(); } public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) { if (imageCache.containsKey(imageUrl)) { SoftReference<Drawable> softReference = imageCache.get(imageUrl); Drawable drawable = softReference.get(); if (drawable != null) { return drawable; } } final Handler handler = new Handler() { public void handleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageUrl); } }; new Thread() { @Override public void run() { Drawable drawable = loadImageFromUrl(imageUrl); imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); } }.start(); return null; } public static Drawable loadImageFromUrl(String url) { URL m; InputStream i = null; try { m = new URL(url); i = (InputStream) m.getContent(); } catch (MalformedURLException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Drawable d = Drawable.createFromStream(i, "src"); return d; } public interface ImageCallback { public void imageLoaded(Drawable imageDrawable, String imageUrl); } }

 

三、ListView适配器

 

Java代码 android ListView 异步加载图片
  1. package com.ning.lazytest;   
  2.   
  3. import java.util.List;   
  4.   
  5. import com.ning.lazytest.AsyncImageLoader.ImageCallback;   
  6.   
  7. import android.app.Activity;   
  8. import android.graphics.drawable.Drawable;   
  9. import android.view.LayoutInflater;   
  10. import android.view.View;   
  11. import android.view.ViewGroup;   
  12. import android.widget.ArrayAdapter;   
  13. import android.widget.ImageView;   
  14. import android.widget.ListView;   
  15. import android.widget.TextView;   
  16.   
  17. public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText>{   
  18.     private ListView listView;   
  19.     private AsyncImageLoader asyncImageLoader;   
  20.        
  21.     public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {   
  22.         super(activity, 0, imageAndTexts);   
  23.         this.listView = listView;   
  24.         asyncImageLoader = new AsyncImageLoader();   
  25.     }   
  26.        
  27.     public View getView(int position, View convertView, ViewGroup parent) {   
  28.         Activity activity = (Activity) getContext();   
  29.   
  30.         // Inflate the views from XML   
  31.         View rowView = convertView;   
  32.         ViewCache viewCache;   
  33.         if (rowView == null) {   
  34.             LayoutInflater inflater = activity.getLayoutInflater();   
  35.             rowView = inflater.inflate(R.layout.image_and_text_row, null);   
  36.             viewCache = new ViewCache(rowView);   
  37.             rowView.setTag(viewCache);   
  38.         } else {   
  39.             viewCache = (ViewCache) rowView.getTag();   
  40.         }   
  41.         ImageAndText imageAndText = getItem(position);   
  42.   
  43.         // Load the image and set it on the ImageView   
  44.         String imageUrl = imageAndText.getImageUrl();   
  45.         ImageView imageView = viewCache.getImageView();   
  46.         imageView.setTag(imageUrl);   
  47.         Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {   
  48.             public void imageLoaded(Drawable imageDrawable, String imageUrl) {   
  49.                 ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);   
  50.                 if (imageViewByTag != null) {   
  51.                     imageViewByTag.setImageDrawable(imageDrawable);   
  52.                 }   
  53.             }   
  54.         });   
  55.         if (cachedImage == null) {   
  56.             imageView.setImageResource(R.drawable.ic_launcher);   
  57.         }else{   
  58.             imageView.setImageDrawable(cachedImage);   
  59.         }   
  60.         // Set the text on the TextView   
  61.         TextView textView = viewCache.getTextView();   
  62.         textView.setText(imageAndText.getText());   
  63.   
  64.         return rowView;   
  65.     }   
  66. }  
package com.ning.lazytest; import java.util.List; import com.ning.lazytest.AsyncImageLoader.ImageCallback; import android.app.Activity; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText>{ private ListView listView; private AsyncImageLoader asyncImageLoader; public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) { super(activity, 0, imageAndTexts); this.listView = listView; asyncImageLoader = new AsyncImageLoader(); } public View getView(int position, View convertView, ViewGroup parent) { Activity activity = (Activity) getContext(); // Inflate the views from XML View rowView = convertView; ViewCache viewCache; if (rowView == null) { LayoutInflater inflater = activity.getLayoutInflater(); rowView = inflater.inflate(R.layout.image_and_text_row, null); viewCache = new ViewCache(rowView); rowView.setTag(viewCache); } else { viewCache = (ViewCache) rowView.getTag(); } ImageAndText imageAndText = getItem(position); // Load the image and set it on the ImageView String imageUrl = imageAndText.getImageUrl(); ImageView imageView = viewCache.getImageView(); imageView.setTag(imageUrl); Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() { public void imageLoaded(Drawable imageDrawable, String imageUrl) { ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl); if (imageViewByTag != null) { imageViewByTag.setImageDrawable(imageDrawable); } } }); if (cachedImage == null) { imageView.setImageResource(R.drawable.ic_launcher); }else{ imageView.setImageDrawable(cachedImage); } // Set the text on the TextView TextView textView = viewCache.getTextView(); textView.setText(imageAndText.getText()); return rowView; } }

 

四、ViewCache 即ListView的每一个Item

 

Java代码 android ListView 异步加载图片
  1. package com.ning.lazytest;   
  2.   
  3. import android.view.View;   
  4. import android.widget.ImageView;   
  5. import android.widget.TextView;   
  6.   
  7. public class ViewCache {   
  8.     private View baseView;   
  9.     private TextView textView;   
  10.     private ImageView imageView;   
  11.   
  12.     public ViewCache(View baseView) {   
  13.         this.baseView = baseView;   
  14.     }   
  15.   
  16.     public TextView getTextView() {   
  17.         if (textView == null) {   
  18.             textView = (TextView) baseView.findViewById(R.id.text);   
  19.         }   
  20.         return textView;   
  21.     }   
  22.   
  23.     public ImageView getImageView() {   
  24.         if (imageView == null) {   
  25.             imageView = (ImageView) baseView.findViewById(R.id.image);   
  26.         }   
  27.         return imageView;   
  28.     }   
  29. }  
package com.ning.lazytest; import android.view.View; import android.widget.ImageView; import android.widget.TextView; public class ViewCache { private View baseView; private TextView textView; private ImageView imageView; public ViewCache(View baseView) { this.baseView = baseView; } public TextView getTextView() { if (textView == null) { textView = (TextView) baseView.findViewById(R.id.text); } return textView; } public ImageView getImageView() { if (imageView == null) { imageView = (ImageView) baseView.findViewById(R.id.image); } return imageView; } }

 

五、Java Bean -> ImageAndText

 

Java代码 android ListView 异步加载图片
  1. package com.ning.lazytest;   
  2.   
  3. public class ImageAndText {   
  4.         private String imageUrl;   
  5.         private String text;   
  6.   
  7.         public ImageAndText(String imageUrl, String text) {   
  8.             this.imageUrl = imageUrl;   
  9.             this.text = text;   
  10.         }   
  11.         public String getImageUrl() {   
  12.             return imageUrl;   
  13.         }   
  14.         public String getText() {   
  15.             return text;   
  16.         }   
  17. }  
package com.ning.lazytest; public class ImageAndText { private String imageUrl; private String text; public ImageAndText(String imageUrl, String text) { this.imageUrl = imageUrl; this.text = text; } public String getImageUrl() { return imageUrl; } public String getText() { return text; } }

 

六、Activity

 

Java代码 android ListView 异步加载图片
  1. package com.ning.lazytest;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;   
  5.   
  6. import android.app.Activity;   
  7. import android.os.Bundle;   
  8. import android.widget.ListView;   
  9.   
  10. public class LazyLoadActivity extends Activity {   
  11.     private String[] myPicUrl = new String[]{   
  12.             "http://imguxv.penshow.cn/uploadfile/2010/04/06/thumb/thumb_250_0_20100406094922546.jpg",   
  13.             "http://imguxv.penshow.cn/uploadfile/2010/04/06/thumb/thumb_250_0_20100406095559309.jpg",   
  14.             "http://imguxv.penshow.cn/uploadfile/2010/04/06/thumb/thumb_250_0_20100406094916270.jpg",   
  15.             "http://imguxv.penshow.cn/uploadfile/2010/04/06/thumb/thumb_250_0_20100406085150824.jpg",   
  16.             "http://imguxv.penshow.cn/uploadfile/2010/04/18/thumb/thumb_250_0_20100418061054239.jpg",   
  17.             "http://imguxv.penshow.cn/uploadfile/2010/04/18/thumb/thumb_250_0_20100418052701708.jpg",   
  18.             "http://imguxv.penshow.cn/uploadfile/2010/04/18/thumb/thumb_250_0_20100418050521586.jpg"  
  19.     };   
  20.     private ImageAndText imageAndText = null;   
  21.     private List<ImageAndText> imageAndTexts = null;   
  22.     private ListView listView = null;   
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {   
  25.         super.onCreate(savedInstanceState);   
  26.         setContentView(R.layout.main);   
  27.            
  28.         imageAndTexts = new ArrayList<ImageAndText>();   
  29.         for(int i = 0;i < myPicUrl.length; i++){   
  30.             imageAndText = new ImageAndText(myPicUrl[i], "Pic " + i);   
  31.             imageAndTexts.add(imageAndText);   
  32.             imageAndText = null;   
  33.         }   
  34.         listView = (ListView)findViewById(R.id.list);   
  35.         listView.setAdapter(new ImageAndTextListAdapter(LazyLoadActivity.this, imageAndTexts, listView));   
  36.     }   
  37. }