ListView异步加载图片实现思路

尛苩丶妖精

尛苩丶妖精

2016-02-19 10:26

在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享ListView异步加载图片实现思路,希望可以对大家能有小小的帮助。
在应用开发中,经常用到ListView去加载数据,加载图片和文字是比较常见的,文字还好,图片从网络请求加载速度比较慢,所以需要把图片的加载放到另一个线程中去执行,执行完了再更新UI线程。以下列出一个我在项目中使用到的异步加载图片的解决方案,代码没有上全,给出核心部分。

大致思路是这样
1.利用软引用来缓存图片Bitmap,用图片的URL作为缓存查找的Key;
2.设两级缓存,一级是SoftReference,二级是本地SD卡;
3.如果两级缓存都没取到图片,则从服务器获取,并加入缓存;
4.加载完后通过回调接口通知UI更新;

以下是异步加载的关键代码,其中一些工具类没有给出,自己实现就可以,比如HttpRequest是我自己写的一个类。
代码如下:

public class AsyncImageLoader {
//Cache for image(Type String is the URL of image,the second parameter is soft reference)
private HashMapString, SoftReferenceBitmap imageCache = null;
private Activity context;
public AsyncImageLoader(Activity context){
this.context = context;
imageCache = new HashMapString, SoftReferenceBitmap();
}
public Bitmap loadImage(final ImageView imageView,final String imageURL,final ImageCallBack imageCallBack){
//If the cache contains the reference of bitmap then return
if (imageCache.containsKey(imageURL)) {
SoftReferenceBitmap bitmapReference = imageCache.get(imageURL);
Bitmap bitmap = bitmapReference.get();
if (bitmap != null) {
return bitmap;
}
}
//Second cache,search local SD card
else {
String fileName = StringUtil.namePicture(imageURL);//获取文件名
boolean isExist = SystemUtils.findPhotoFromSDCard(Constant.INFO_PATH, fileName);
if (isExist) {//是否在SD卡存在图片
Bitmap bitmap = SystemUtils.getPhotoFromSDCard(Constant.INFO_PATH, fileName);
return bitmap;
}
}
final Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg)
{
imageCallBack.setImage(imageView, (Bitmap)msg.obj);
}
};
//If the bitmap not exists in cache or SD card,then get it from net
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
boolean isNetwork = SystemUtils.checkNetwork(context);
if (isNetwork) {
InputStream photoStream = HttpRequest.getImageStream(imageURL);//这里是我自己写的一个类,目的是通过URL地址从服务器获取图片输入流
Bitmap bitmap;
try {
bitmap = ImageTools.getResizeBitmap(photoStream, 128, 128);
if (bitmap != null) {
String fileName = StringUtil.namePicture(imageURL);
//Save image to SD card
SystemUtils.savePhotoToSDCard(bitmap, fileName, Constant.INFO_PATH);
//Put soft reference to cache
imageCache.put(imageURL, new SoftReferenceBitmap(bitmap));
//Send message to update UI
Message message = myHandler.obtainMessage(0, bitmap);
myHandler.sendMessage(message);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
return null;
}
/**
* Interface for load image
* @author Ryan
*
*/
public interface ImageCallBack{
//Set image for imageview through bitmap
public void setImage(ImageView imageView,Bitmap bitmap);
}
}

在ListView的adapter的getView方法中:
代码如下:

Bitmap bitmap1 = asyncImageLoader.loadImage(viewHolder.imageView1, url1, new ImageCallBack() {
@Override
public void setImage(ImageView imageView, Bitmap bitmap) {
// TODO Auto-generated method stub
imageView.setImageBitmap(bitmap);
}
});
if (bitmap1 != null) {
viewHolder.imageView1.setImageBitmap(bitmap1);
}else {
viewHolder.imageView1.setImageResource(R.drawable.image_bg);
}

其中asyncImageLoader是在adapter的构造方法中初始化的,形成一个缓存。通过这个机制就可以实现ListView的图片异步加载,在用户体验上比直接加载要感觉好很多,那样会造成界面卡顿。这里是加载一张图片的情况,如果ListView的item中的图片是不定的,有可能是一张、两张、三张,该用什么方式呢,大家可以思考一下,并可以一起讨论一下,包括实现ListView滚动时不加载数据也是优化ListView加载的必要步骤。
展开更多 50%)
分享

猜你喜欢

ListView异步加载图片实现思路

编程语言 网络编程
ListView异步加载图片实现思路

ListView异步加载图片实现思路(优化篇)

编程语言 网络编程
ListView异步加载图片实现思路(优化篇)

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

android异步加载图片并缓存到本地实现方法

编程语言 网络编程
android异步加载图片并缓存到本地实现方法

ios通过按钮点击异步加载图片

编程语言 网络编程
ios通过按钮点击异步加载图片

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

ListView 分页加载更新实例分享

编程语言 网络编程
ListView 分页加载更新实例分享

VB精彩教程:数据异步加载

编程语言 网络编程
VB精彩教程:数据异步加载

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

Ajax初试之读取数据篇实现代码

Ajax初试之读取数据篇实现代码

MYSQL WHERE语句优化

MYSQL WHERE语句优化
下拉加载更多内容 ↓