如何高效使用和管理Bitmap--图片缓存管理模块的设计与实现

本文详细介绍了在Android 4.0以上平台如何设计和实现Bitmap的内存及磁盘缓存机制,包括图片加载流程、内存缓存类(PanoMemCache)、磁盘缓存类(PanoDiskCache)、图片工具类(PanoUtils)的使用,以及工作线程池化的管理策略。
摘要由CSDN通过智能技术生成

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

        上周为360全景项目引入了图片缓存模块。因为是在Android4.0平台以上运作,出于惯性,都会在设计之前查阅相关资料,尽量避免拿一些以前2.3平台积累的经验来进行类比处理。开发文档中有一个BitmapFun的示例,仔细拜读了一下,虽说围绕着Bitmap的方方面面讲得都很深入,但感觉很难引入到当前项目中去。

        现在的图片服务提供者基本上都来源于网络。对于应用平台而言,访问网络属于耗时操作。尤其是在移动终端设备上,它的显著表现为系统的延迟时间变长、用户交互性变差等。可以想象,一个携带着这些问题的应用在市场上是很难与同类产品竞争的。
        说明一下,本文借鉴了 Keegan小钢和安卓巴士的处理模板,主要针对的是4.0以上平台应用。2.3以前平台执行效果未知,请斟酌使用或直接略过:),当然更欢迎您把测试结果告知笔者。

1图片加载流程

        首先,我们谈谈加载图片的流程,项目中的该模块处理流程如下:

        在UI主线程中,从内存缓存中获取图片,找到后返回。找不到进入下一步;
        在工作线程中,从磁盘缓存中获取图片,找到即返回并更新内存缓存。找不到进入下一步;
        在工作线程中,从网络中获取图片,找到即返回并同时更新内存缓存和磁盘缓存。找不到显示默认以提示。

2内存缓存类(PanoMemCache)

        这里使用Android提供的LruCache类,该类保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。当cache已满的时候加入新的item时,在队列尾部的item会被回收。

public class PanoMemoryCache {

    // LinkedHashMap初始容量
    private static final int INITIAL_CAPACITY = 16;
    // LinkedHashMap加载因子
    private static final float LOAD_FACTOR = 0.75f;
    // LinkedHashMap排序模式
    private static final boolean ACCESS_ORDER = true;

    // 软引用缓存
    private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache;
    // 硬引用缓存
    private static LruCache<String, Bitmap> mLruCache;
    
    public PanoMemoryCache() {
	// 获取单个进程可用内存的最大值
	// 方式一:使用ActivityManager服务(计量单位为M)
        /*int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();*/
	// 方式二:使用Runtime类(计量单位为Byte)
        final int memClass = (int) Runtime.getRuntime().maxMemory();
        // 设置为可用内存的1/4(按Byte计算)
        final int cacheSize = memClass / 4;
        mLruCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                if(value != null) {
                    // 计算存储bitmap所占用的字节数
                    return value.getRowBytes() * value.getHeight();
                } else {
                    return 0;
                }
            }
            
            @Override
            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
                if(oldValue != null) {
                    // 当硬引用缓存容量已满时,会使用LRU算法将最近没有被使用的图片转入软引用缓存
                    mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));
                }
            }
        };
        
	/*
	* 第一个参数:初始容量(默认16)
	* 第二个参数:加载因子(默认0.75)
	* 第三个参数:排序模式(true:按访问次数排序;false:按插入顺序排序)
	*/
        mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(INIT
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值