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====================
这个代码中 在 ImageCallBack 接口中 吧imageUrl 回传回来,跟imageView.getTag() 进行比较,应该可以解决问题。试试看。