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() 进行比较,应该可以解决问题。试试看。
posted @ 2014-11-12 10:25  0基础学android开发  阅读(179)  评论(0编辑  收藏  举报
我要啦免费统计