android listview 异步加载问题


====================问题描述====================
学做android,自己想模仿QQ空间做一个小demo
listview异步加载图片的时候遇到了一个问题
异步加载用到了SoftReference 和文件缓存的方法
每次加载图片的时候,也在内存或缓存中找到了图片
第一次加载出来后,listview滑动了,同样也进到了setImageBitmap这一步
可是就是图片显示不出来变成空白
下面帖几张图和代码
滑动前

滑动后
Image_url = new StringBuffer(AppConstant.DOWNLOAD_IMAGE_URL)
.append(msg.getOPImageList().get(0).getImageUrl())
.toString();

ImageView imageView = holder.msgImage;
imageView.setTag(Image_url);
Bitmap bitmap = Loader.loadBitmap(imageView, Image_url,
new ImageCallBack() {
@Override
public void imageLoad(ImageView imageView, Bitmap bitmap) {
if (imageView.getTag() != null
&& imageView.getTag().equals(Image_url)) {
imageView.setImageBitmap(bitmap);
}
}
});
Log.e("当前的postion", "" + position);
if (bitmap == null) {
imageView.setImageDrawable(context.getResources().getDrawable(
R.drawable.ic_launcher));
} else {
imageView.setImageBitmap(bitmap);
}

loader
public class Loader {
/**
 * 内存图片软引用缓冲
 */
private static HashMap<String, SoftReference<Bitmap>> imageCache = null;

public Loader() {
imageCache = new HashMap<String, SoftReference<Bitmap>>();
}

public static String getFileName(String url) {
return url.substring(url.lastIndexOf(File.separator) + 1);
}

public static Bitmap getLocalResource(String destDir, String imageName) {

Bitmap bmp = null;
File imgeDir = new File(destDir);
File cache = null;
if (!imgeDir.exists()) { // 判断本地缓存目录是否存在
imgeDir.mkdirs();
} else {
cache = new File(destDir + File.separator + imageName); // 判断该图片资源是否存在

if (cache.exists()) { // 如果存在就根据图片的存储路径得到Bitmap对象 bm

bmp = BitmapFactory.decodeFile(cache.getAbsolutePath());
}
}
return bmp;
}

public static Bitmap loadBitmap(final ImageView imageView, final String imageURL,
final ImageCallBack imageCallBack) {
// 在内存缓存中,则返回Bitmap对象
if (imageCache.containsKey(imageURL)) {
SoftReference<Bitmap> reference = imageCache.get(imageURL);
Bitmap bitmap = reference.get();
if (bitmap != null) {
return bitmap;
}
} else {
/**
 * 加上一个对本地缓存的查找
 */
String bitmapName = imageURL
.substring(imageURL.lastIndexOf("/") + 1);
Bitmap bitmapTemp = null;
bitmapTemp = getLocalResource(AppConstant.TEST, bitmapName);
if (bitmapTemp != null) {
return bitmapTemp;
}
}

final Handler handler = new Handler() {
/*
 * (non-Javadoc)
 * 
 * @see android.os.Handler#handleMessage(android.os.Message)
 */
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
imageCallBack.imageLoad(imageView, (Bitmap) msg.obj);
}
};

// 如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
new Thread() {
/*
 * (non-Javadoc)
 * 
 * @see java.lang.Thread#run()
 */
@Override
public void run() {
// TODO Auto-generated method stub
Bitmap bitmap = null;
try {

URL imageUrl = new URL(imageURL);
HttpURLConnection conn =  (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
// InputStream is = conn.getInputStream();

InputStream in = conn.getInputStream();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 10; // width,hight设为原来的十分一
bitmap = BitmapFactory.decodeStream(in, null, options);
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);

File dir = new File(AppConstant.TEST);
if (!dir.exists()) {
dir.mkdirs();
}

File bitmapFile = new File(AppConstant.TEST + File.separator
+ imageURL.substring(imageURL.lastIndexOf("/") + 1));
if (!bitmapFile.exists()) {
try {
bitmapFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
FileOutputStream fos;
try {
fos = new FileOutputStream(bitmapFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();

return null;
}

/**
 * 回调接口
 * 
 * @author onerain
 * 
 */
public interface ImageCallBack {
public void imageLoad(ImageView imageView, Bitmap bitmap);
}
}

坐等大神支招啊
每次都进了setimagebitmap这一步 就是加载不出图片


====================解决方案1====================
你用imageLoader这个三方开源库试试。
====================解决方案2====================
看一下你imageview控件设的是src还是background。或者试试把bitmap转成drawable,再setbackground试试
====================解决方案3====================
看下getView方法?
====================解决方案4====================
贴下Adapter的代码看看呗
====================解决方案5====================
你试试AsyncImage这个第三方开源库
====================解决方案6====================
  ImageView imageViewByTag = (ImageView) listview 
                                .findViewWithTag(imageUrl); 

问题应该在这一句 你这个搜索 只会找到第一个TAG 是imageUrl的控件。 可能并不是你的要更新的控件。

比如  你setTAG了  , listView 会重用item的,   在 msg.getOPImageList().size()=0 时候 还是有这个tag。  
然后你find的结果就是这个contentView里面的,不是你要更新的那个ImageView。 
====================解决方案7====================
引用
Image_url = new StringBuffer(AppConstant.DOWNLOAD_IMAGE_URL)
.append(msg.getOPImageList().get(0).getImageUrl())
.toString();

ImageView imageView = holder.msgImage;
imageView.setTag(Image_url);
Bitmap bitmap = Loader.loadBitmap(imageView, Image_url,
new ImageCallBack() {
@Override
public void imageLoad(ImageView imageView, Bitmap bitmap) {
if (imageView.getTag() != null
&& imageView.getTag().equals(Image_url)) {
imageView.setImageBitmap(bitmap);
}
}
});
Log.e("当前的postion", "" + position);
if (bitmap == null) {
imageView.setImageDrawable(context.getResources().getDrawable(
R.drawable.ic_launcher));
} else {
imageView.setImageBitmap(bitmap);
}



这个代码中  在 ImageCallBack 接口中 吧imageUrl 回传回来,跟imageView.getTag() 进行比较,应该可以解决问题。试试看。
原文地址:https://www.cnblogs.com/lianxu61/p/4002195.html