解决ListView中在滚动时已经下载缓存的图片没有显示
2015-07-21 00:00
501 查看
摘要: 这几天为了解决ListView在滚动时已经下载缓存的图片时而显示,时而不显示的问题,在网上找了不少资料,伤了不少的脑细胞,终于找到最好的解决方法
这几天为了解决ListView在滚动时已经下载缓存的图片时而显示,时而不显示的问题,在网上找了不少资料,伤了不少的脑细胞,而昨天虽然找到了解决方法但发现这种方法非常占资源,执行起来不顺畅,有卡的现象,今天又在网上找了一些资料,终于找到最好的解决方法,现在将解决方案做下记录
1、异步加载图片代码:
2、判断是否已经存在下载缓存图片方法:
3、adapter 中的代码:
以上我在Android 4.0.3 以上测试是完全没有问题,因为我现在开发都是基于4.0环境来开发的
这几天为了解决ListView在滚动时已经下载缓存的图片时而显示,时而不显示的问题,在网上找了不少资料,伤了不少的脑细胞,而昨天虽然找到了解决方法但发现这种方法非常占资源,执行起来不顺畅,有卡的现象,今天又在网上找了一些资料,终于找到最好的解决方法,现在将解决方案做下记录
1、异步加载图片代码:
import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.content.Context; import android.graphics.Bitmap; import android.os.Handler; import android.util.Log; public class AsyncImageLoader { //保存正在下载的图片URL集合,避免重复下载用 private static HashSet<String> sDownloadingSet; //软引用内存缓存 private static Map<String, SoftReference<Bitmap>> sImageCache; //图片三种获取方式管理者,网络URL获取、内存缓存获取、外部文件缓存获取 private static LoaderImpl impl; //线程池相关 private static ExecutorService sExecutorService; //通知UI线程图片获取ok时使用 private Handler handler; /** * 异步加载图片完毕的回调接口 */ public interface ImageCallback { /** * 回调函数 * * @param bitmap: may be null! * @param imageUrl */ public void onImageLoaded(Bitmap bitmap, String imageUrl); } static { sDownloadingSet = new HashSet<String>(); sImageCache = new HashMap<String, SoftReference<Bitmap>>(); impl = new LoaderImpl(sImageCache); } public AsyncImageLoader(Context context) { handler = new Handler(); startThreadPoolIfNecessary(); String defaultDir = context.getCacheDir().getAbsolutePath(); setCachedDir(defaultDir); } /** * 是否缓存图片至/data/data/package/cache/目录 * 默认不缓存 */ public void setCache2File(boolean flag) { impl.setCache2File(flag); } /** * 设置缓存路径,setCache2File(true)时有效 */ public void setCachedDir(String dir) { impl.setCachedDir(dir); } /** * 开启线程池 */ public static void startThreadPoolIfNecessary() { if (sExecutorService == null || sExecutorService.isShutdown() || sExecutorService.isTerminated()) { sExecutorService = Executors.newFixedThreadPool(3); //sExecutorService = Executors.newSingleThreadExecutor(); } } /** * 异步下载图片,并缓存到memory中 * * @param url * @param callback see ImageCallback interface */ public void downloadImage(final String url, final ImageCallback callback) { downloadImage(url, true, callback); } /** * @param url * @param cache2Memory 是否缓存至memory中 * @param callback */ public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback) { if (sDownloadingSet.contains(url)) { Log.i("AsyncImageLoader", "###该图片正在下载,不能重复下载!"); return; } Bitmap bitmap = impl.getBitmapFromMemory(url); if (bitmap != null) { if (callback != null) { callback.onImageLoaded(bitmap, url); } } else { //从网络端下载图片 sDownloadingSet.add(url); sExecutorService.submit(new Runnable() { @Override public void run() { final Bitmap bitmap = impl.getBitmapFromUrl(url, cache2Memory); handler.post(new Runnable() { @Override public void run() { if (callback != null) callback.onImageLoaded(bitmap, url); sDownloadingSet.remove(url); } }); } }); } } /** * 预加载下一张图片,缓存至memory中 * * @param url */ public void preLoadNextImage(final String url) { //将callback置为空,只将bitmap缓存到memory即可。 downloadImage(url, null); } }
2、判断是否已经存在下载缓存图片方法:
//加载图片 public static Bitmap getURLImage(Context context, String key, LruCache<String, Bitmap> lruCache) { Bitmap bitmap = lruCache.get(key); // 判断是否已经存在缓存图片 if (bitmap == null) { //如果不存在就自动异步加载 bitmap = initAsyncImageLoader(context, key); } return bitmap; } private static Bitmap initAsyncImageLoader(Context context, String url) { final Bitmap[] bmp = {null}; AsyncImageLoader loader = new AsyncImageLoader(context.getApplicationContext()); //将图片缓存至外部文件中 loader.setCache2File(true); //设置外部缓存文件夹 createCacheDir(context, "image"); loader.setCachedDir(dirPath); //下载图片,第二个参数是否缓存至内存中 loader.downloadImage(url, true, new AsyncImageLoader.ImageCallback() { @Override public void onImageLoaded(Bitmap bitmap, String imageUrl) { bmp[0] = bitmap; } }); return bmp[0]; }
3、adapter 中的代码:
//获取当前应用程序所分配的最大内存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); //只分5分之一用来做图片缓存 int cacheSize = maxMemory / 5; LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { //复写sizeof()方法 //这里是按多少KB来算 return value.getRowBytes() * value.getHeight() / 1024; } }; @Override public View getView(int position, View convertView, ViewGroup parent) { JSONObject item_data = getItem(position); if (convertView != null) { //节约视图资源 ll = (LinearLayout) convertView.getTag(); ImageView imageView_image = (ImageView) ll.findViewById(R.id.imageview_image); imageView_image.setImageResource(R.drawable.iconfont_loading); } else { ll = (LinearLayout) LayoutInflater.from(mcontext).inflate(R.layout.adapter_listview_product, null); ll.setTag(ll); } ImageView imageView_image = (ImageView) ll.findViewById(R.id.imageview_image); try { String offerId = String.valueOf(item_data.getString("offerId")); //图片资源 String image_url = item_data.getString("image"); imageView_image.setTag(offerId); //得到可用的图片 if (offerId == imageView_image.getTag()) { Bitmap bitmap = FileUtil.getURLImage(mcontext, image_url, mLruCache); if (bitmap != null) { if (mLruCache.get(image_url) == null) { mLruCache.put(image_url,bitmap); } imageView_image.setImageBitmap(bitmap); } else { imageView_image.setImageResource(R.drawable.iconfont_loading); } } textView_saledCount.setText(String.valueOf(item_data.getInt("saledCount"))); } catch (JSONException e) { e.printStackTrace(); } return ll;
以上我在Android 4.0.3 以上测试是完全没有问题,因为我现在开发都是基于4.0环境来开发的
相关文章推荐
- 完美实现Android ListView中的TextView的跑马灯效果
- Scrapy的架构介绍
- 发布一个自己做的jsp博客系统
- android上改变listView的选中颜色
- 提供个 全免杀海洋2006asp木马 下载
- 高手写的Tracer-Flash代码调试类代码下载
- Vista 防火墙 Vista Firewall Control v1.0.11 下载
- 国外Lightbox v2.03.3 最新版 下载
- 火影漫画下载助手 下载
- USBkill U盘防火墙 v3.0 下载
- 腾讯 Tencent Traveler v3.4 下载
- 查杀软件 360安全卫士 v3.2.1.1001 下载
- Kaspersky 6.0.2.666 MP2 nct Release+汉化补丁 下载
- Symantec Norton Ghost v12.0 Retail ISO 多国语言版 下载
- Delphi7中Listview的常用功能汇总
- Delphi控件ListView的属性及使用方法详解
- 电脑硬件分析Ultimate Boot CD v4.1.1 下载
- 花香盈路7.6商业美化版 下载
- Orca (Msi文件编辑器) 3.1.4000.1830 修正 汉化版 下载
- 办公室文档模板集合 下载