更好的是,您可以通过 ImageManager 类使用 SoftReference。
在您的 ListAdpater getView() 方法中调用 ImageManager 的 displayImage() 方法。
ImageManager 编码示例:
public class ImageManagerExemple {
private static final String LOG_TAG = "ImageManager";
private static ImageManagerExemple instance = null;
public static ImageManagerExemple getInstance(Context context) {
if (instance == null) {
instance = new ImageManagerExemple(context);
}
return instance;
}
private HashMap<String, SoftReference<Bitmap>> imageMap = new HashMap<String, SoftReference<Bitmap>>();
private Context context;
private File cacheDir;
private ImageManagerExemple(Context context) {
this.context = context;
// Find the dir to save cached images
String sdState = android.os.Environment.getExternalStorageState();
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
File sdDir = android.os.Environment.getExternalStorageDirectory();
cacheDir = new File(sdDir,"data/yourappname");
} else {
cacheDir = context.getCacheDir();
}
if(!cacheDir.exists()) {
cacheDir.mkdirs();
}
}
/**
* Display web Image loading thread
* @param imageUrl picture web url
* @param imageView target
* @param imageWaitRef picture during loading
*/
public void displayImage(String imageUrl, ImageView imageView, Integer imageWaitRef) {
String imageKey = imageUrl;
imageView.setTag(imageKey);
if(imageMap.containsKey(imageKey) && imageMap.get(imageKey).get() != null) {
Bitmap bmp = imageMap.get(imageKey).get();
imageView.setImageBitmap(bmp);
} else {
queueImage(imageUrl, imageView);
if(imageWaitRef != null)
imageView.setImageResource(imageWaitRef);
}
}
private void queueImage(String url, ImageView imageView) {
ImageRef imgRef=new ImageRef(url, imageView);
// Start thread
Thread imageLoaderThread = new Thread(new ImageQueueManager(imgRef));
// Make background thread low priority, to avoid affecting UI performance
imageLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
imageLoaderThread.start();
}
private Bitmap getBitmap(String url) {
String filename = String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
try {
// Is the bitmap in our cache?
Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null) return bitmap;
// Nope, have to download it
bitmap = ImageServerUtils.pictureUrlToBitmap(url);
// save bitmap to cache for later
writeFile(bitmap, f);
return bitmap;
} catch (Exception ex) {
ex.printStackTrace();
Log.e(LOG_TAG, ""+ex.getLocalizedMessage());
return null;
} catch (OutOfMemoryError e) {
Log.e(LOG_TAG, "OutOfMemoryError : "+e.getLocalizedMessage());
e.printStackTrace();
return null;
}
}
private void writeFile(Bitmap bmp, File f) {
if (bmp != null && f != null) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
//bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
bmp.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (Exception e) {
e.printStackTrace();
}
finally {
try { if (out != null ) out.close(); }
catch(Exception ex) {}
}
}
}
private class ImageRef {
public String imageUrl;
public ImageView imageView;
public ImageRef(String imageUrl, ImageView i) {
this.imageUrl=imageUrl;
this.imageView=i;
}
}
private class ImageQueueManager implements Runnable {
private ImageRef imageRef;
public ImageQueueManager(ImageRef imageRef) {
super();
this.imageRef = imageRef;
}
@Override
public void run() {
ImageRef imageToLoad = this.imageRef;
if (imageToLoad != null) {
Bitmap bmp = getBitmap(imageToLoad.imageUrl);
String imageKey = imageToLoad.imageUrl;
imageMap.put(imageKey, new SoftReference<Bitmap>(bmp));
Object tag = imageToLoad.imageView.getTag();
// Make sure we have the right view - thread safety defender
if (tag != null && ((String)tag).equals(imageKey)) {
BitmapDisplayer bmpDisplayer = new BitmapDisplayer(bmp, imageToLoad.imageView);
Activity a = (Activity)imageToLoad.imageView.getContext();
a.runOnUiThread(bmpDisplayer);
}
}
}
}
//Used to display bitmap in the UI thread
private class BitmapDisplayer implements Runnable {
Bitmap bitmap;
ImageView imageView;
public BitmapDisplayer(Bitmap b, ImageView i) {
bitmap=b;
imageView=i;
}
@Override
public void run() {
if(bitmap != null) {
imageView.setImageBitmap(bitmap);
}
}
}