ListView异步加载图片

在应用开发中,经常用到ListView去加载数据,加载图片和文字是比较常见的,文字还好,图片从网络请求加载速度比较慢,所以需要把图片的加载放到另一个线程中去执行,执行完了再更新UI线程。以下列出一个我在项目中使用到的异步加载图片的解决方案,代码没有上全,给出核心部分。



大致思路是这样:

1.利用软引用来缓存图片Bitmap,用图片的URL作为缓存查找的Key;

2.设两级缓存,一级是SoftReference,二级是本地SD卡;

3.如果两级缓存都没取到图片,则从服务器获取,并加入缓存;

4.加载完后通过回调接口通知UI更新;



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



[java] view plaincopy
01.public class AsyncImageLoader {
02.
03. //Cache for image(Type String is the URL of image,the second parameter is soft reference)
04. private HashMap<String, SoftReference<Bitmap>> imageCache = null;
05. private Activity context;
06.
07. public AsyncImageLoader(Activity context){
08. this.context = context;
09. imageCache = new HashMap<String, SoftReference<Bitmap>>();
10. }
11.
12. public Bitmap loadImage(final ImageView imageView,final String imageURL,final ImageCallBack imageCallBack){
13.
14. //If the cache contains the reference of bitmap then return
15. if (imageCache.containsKey(imageURL)) {
16. SoftReference<Bitmap> bitmapReference = imageCache.get(imageURL);
17. Bitmap bitmap = bitmapReference.get();
18. if (bitmap != null) {
19. return bitmap;
20. }
21. }
22. //Second cache,search local SD card
23. else {
24. String fileName = StringUtil.namePicture(imageURL);//获取文件名
25. boolean isExist = SystemUtils.findPhotoFromSDCard(Constant.INFO_PATH, fileName);
26. if (isExist) {//是否在SD卡存在图片
27. Bitmap bitmap = SystemUtils.getPhotoFromSDCard(Constant.INFO_PATH, fileName);
28. return bitmap;
29. }
30.
31. }
32.
33. final Handler myHandler = new Handler(){
34.
35. @Override
36. <span style="white-space: pre;"> </span> public void handleMessage(Message msg)
37. <span style="white-space: pre;"> </span>{
38. <span style="white-space: pre;"> </span>imageCallBack.setImage(imageView, (Bitmap)msg.obj);
39. <span style="white-space: pre;"> </span>}
40. };
41.
42. //If the bitmap not exists in cache or SD card,then get it from net
43. new Thread(){
44.
45. @Override
46. public void run() {
47. // TODO Auto-generated method stub
48. boolean isNetwork = SystemUtils.checkNetwork(context);
49. if (isNetwork) {
50. InputStream photoStream = HttpRequest.getImageStream(imageURL);//这里是我自己写的一个类,目的是通过URL地址从服务器获取图片输入流
51. Bitmap bitmap;
52. try {
53. bitmap = ImageTools.getResizeBitmap(photoStream, 128, 128);
54. if (bitmap != null) {
55. String fileName = StringUtil.namePicture(imageURL);
56. //Save image to SD card
57. SystemUtils.savePhotoToSDCard(bitmap, fileName, Constant.INFO_PATH);
58. //Put soft reference to cache
59. imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));
60. //Send message to update UI
61. Message message = myHandler.obtainMessage(0, bitmap);
62. myHandler.sendMessage(message);
63. }
64. } catch (Exception e) {
65. // TODO Auto-generated catch block
66. e.printStackTrace();
67. }
68. }
69. }
70. }.start();
71.
72. return null;
73. }
74.
75. /**
76. * Interface for load image
77. * @author Ryan
78. *
79. */
80. public interface ImageCallBack{
81. //Set image for imageview through bitmap
82. public void setImage(ImageView imageView,Bitmap bitmap);
83. }
84.
85.}

在ListView的adapter的getView方法中:


[java] view plaincopy
01.Bitmap bitmap1 = asyncImageLoader.loadImage(viewHolder.imageView1, url1, new ImageCallBack() {
02.
03. @Override
04. public void setImage(ImageView imageView, Bitmap bitmap) {
05. // TODO Auto-generated method stub
06. imageView.setImageBitmap(bitmap);
07. }
08. });
09.
10. if (bitmap1 != null) {
11. viewHolder.imageView1.setImageBitmap(bitmap1);
12. }else {
13. viewHolder.imageView1.setImageResource(R.drawable.image_bg);
14. }

其中asyncImageLoader是在adapter的构造方法中初始化的,形成一个缓存。通过这个机制就可以实现ListView的图片异步加载,在用户体验上比直接加载要感觉好很多,那样会造成界面卡顿。这里是加载一张图片的情况,如果ListView的item中的图片是不定的,有可能是一张、两张、三张,该用什么方式呢,大家
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值