- 浏览: 17786 次
- 性别:
- 来自: 南京
最新评论
在应用开发中,经常用到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中的图片是不定的,有可能是一张、两张、三张,该用什么方式呢,大家
大致思路是这样:
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中的图片是不定的,有可能是一张、两张、三张,该用什么方式呢,大家
发表评论
-
Android应用如何监听自己是否被卸载及卸载反馈功能的实现(第三版)
2015-01-26 21:04 718两个月前发了两篇有关 ... -
移动端与PHP服务端接口通信流程设计(增强版)
2014-11-21 14:37 592前面讲过:移动端与PHP服务端接口通信流程设计(基础版) 对 ... -
移动端与PHP服务端接口通信流程设计(基础版)
2014-11-21 14:19 668针对 --->非开放性平台 --->公司内部产 ... -
Android WebView与JS交互及消息处理
2014-11-06 19:07 686前一段时间做公司的项目,涉及到WebView与JS之间的通信, ... -
解决video标签在安卓webview下无法自动播放问题
2014-11-05 19:50 2083安卓webview下 html5 的 video 设置au ... -
android 为一个apk设置多个ICON图标和执行入口
2014-07-12 11:34 1065在Android开发中,一个工程对应一个AndroidMani ... -
如何在Android中启动JAVA程序
2014-05-27 20:20 448在Android中启动JAVA程序 ... -
Android root的两种方法-udev漏洞和setuid漏洞
2014-05-19 19:54 919转载自:http://intrepidusgroup.com/ ... -
Android Root 1 —— RageAgainstTheCage
2014-05-19 19:45 1190这个漏洞网上有很多资 ... -
android 使用include 调用内部组件
2014-05-09 10:44 602例子一: sublayout.xml <?xml ... -
Android系统设计中存在设计模式分析
2013-12-18 18:52 7821、 开闭(OCP) 简介:要扩展,不要修改。比如我对外提供 ...
相关推荐
本实例将详细讲解如何实现“Android ListView异步加载图片”,结合线程池、数据库和本地保存来优化性能。 首先,我们需要理解异步加载的概念。在Android中,由于主线程负责用户界面的更新,因此不应在主线程中执行...
"Android实现ListView异步加载图片" Android 实现 ListView 异步加载图片是一种常见的技术,旨在提高应用程序的性能和用户体验。本文将详细介绍 Android 中实现 ListView 异步加载图片的方法,并对相关的技术概念...
因此,"ListView异步加载图片"是解决这一问题的关键技术。本文将详细介绍如何在ListView中实现图片的异步加载,提升用户体验。 1. **AsyncTask**:Android提供了异步处理任务的工具类AsyncTask,可以用来加载图片。...
这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...
综上所述,实现ListView中的异步加载图片进度条,需要综合运用多线程、图片缓存、UI更新等技术,并遵循良好的代码组织和错误处理原则。通过合理的封装和接口设计,可以使得代码更加规范,同时也提升了用户体验。
因此,"ListView异步加载图片"是一个重要的优化策略,旨在提高用户体验并减少资源消耗。 1. **异步加载原理**: 异步加载图片的核心思想是将耗时的网络请求和图片解码操作放在后台线程执行,避免阻塞UI主线程。...
在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。...综上所述,Android ListView异步加载图片是提高应用性能的关键技术,通过合理的线程管理和第三方库,我们可以高效、便捷地实现这一功能。
"官方 listview 异步加载图片"这个主题就是关于如何在ListView中高效、平滑地加载图片的技术实践。 异步加载的基本原理是在主线程之外(通常在后台线程)加载图片,避免阻塞UI更新,从而保证界面的流畅性。在这个...
在本项目"listview 异步加载图片,滑动删除"中,开发者实现了一个功能完善的ListView,它不仅能够异步加载图片,还支持用户通过滑动来删除列表项。 1. **异步加载图片**:异步加载是一种优化策略,避免阻塞主线程,...
因此,"ListView异步加载图片实例"是一个重要的优化策略,它的目的是在不阻塞主线程的情况下加载图片,提升用户体验。 异步加载图片的基本原理是将图片的加载工作放在后台线程执行,完成后再更新到ListView的相应...
本文将基于提供的"listview 异步加载图片源代码",详细讲解如何实现ListView中图片的异步加载。 首先,异步加载图片的核心思想是将耗时的操作,即图片的下载和解码工作,放到后台线程进行,避免阻塞主线程。这样...
Android 异步加载图片,对ListView的异步加载图片的功能演示,主要根据url读取图片返回流的方法。为了方便演示,将请求图片的链接先固定,每读取好一个图片就更新,界面比较简单,当然你可以做成比较好的,像很多好...