您的位置:首页 > 移动开发 > Android开发

android listview 异步加载问题

2014-11-12 10:25 417 查看
============问题描述============

学做android,自己想模仿QQ空间做一个小demo

listview异步加载图片的时候遇到了一个问题

异步加载用到了SoftReference 和文件缓存的方法

每次加载图片的时候,也在内存或缓存中找到了图片

第一次加载出来后,listview滑动了,同样也进到了setImageBitmap这一步

可是就是图片显示不出来变成空白

下面帖几张图和代码

滑动前



滑动后


loaderpublic 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() 进行比较,应该可以解决问题。试试看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: