前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Android 内存优化】Bitmap 内存缓存 ( Bitmap 缓存策略 | LruCache 内存缓存 | LruCache 常用操作 | 工具类代码 )

【Android 内存优化】Bitmap 内存缓存 ( Bitmap 缓存策略 | LruCache 内存缓存 | LruCache 常用操作 | 工具类代码 )

作者头像
韩曙亮
发布于 2023-03-27 13:55:30
发布于 2023-03-27 13:55:30
2.2K00
代码可运行
举报
运行总次数:0
代码可运行

文章目录

官方参考 : Google 官方提供的 内存优化参考 ;

Glide 开源库 : 官方建议凡是使用到 Bitmap 解码 , 显示 , 缓存等操作 , 直接使用 Glide 开源库进行上述操作 , 不建议直接操作 Bitmap 对象 ;

一、Bitmap 内存缓存策略


1 . Android 2.3.3(API 级别 10)及以下的版本中 , 使用 Bitmap 对象的 recycle 方法回收内存 ;

2 . Android 3.0(API 级别 11)及以上的版本中 , 使用新引入的 Bitmap 内存复用机制 , 通过设置 BitmapFactory.Options.inBitmap 字段 , 图像解码时 , 会尝试复用该设置的 inBitmap 内存 , 该内存复用有以下限制 :

① Android 4.4(API 级别 19)及以上的版本 : 在 Android 4.4(API 级别 19)及以上的版本中 , 只要被解码后的 Bitmap 对象的字节大小 , 小于等于 inBitmap 的字节大小 , 就可以复用成功 ; 解码后的乳香可以是缩小后的 , 即 BitmapFactory.Options.inSampleSize 可以大于1 ;

② Android 4.4(API 级别 19)以下的版本 : 在 Android 4.4(API 级别 19) 之前的代码中 , 复用的前提是必须同时满足以下

3

个条件 :

  • 被解码的图像必须是 JPEG 或 PNG 格式
  • 被复用的图像宽高必须等于 解码后的图像宽高
  • 解码图像的 BitmapFactory.Options.inSampleSize 设置为 1 , 也就是不能缩放

才能复用成功 , 另外被复用的图像的像素格式 Config ( 如 RGB_565 ) 会覆盖设置的 BitmapFactory.Options.inPreferredConfig 参数 ;

二、LruCache 内存缓存


1 . LruCache 简介 : 内存缓存一般使用 LruCache , 在 【Android 应用开发】LruCache 简介 博客中有简要介绍 ;

① LRU 算法 : LruCache 使用 LRU ( Least Recently Used 最近最少使用 ) 算法 , 其内部维护了一个 LinkedHashMap 队列 ;

② LRU 数据淘汰原理 : 最近最少使用的数据 , 将会被淘汰 ;

③ LRU 缓存数据优先级 : 如果某数据最近被访问过 , 那么之后的一段时间可能被访问的几率增加 , 其优先级提高 , 如果某数据很长时间没有访问 , 其优先级会被降低 ; 当 LruCache 缓存的内存数据达到了设定的缓存大小 , 低优先级的数据会被先淘汰 ;

2 . 数据结构 : 该队列使用双向链表实现 , 实际存放内存数据的是 LinkedHashMap 集合 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 这是定义杂 LruCache 中的内部集合
private final LinkedHashMap<K, V> map;

3 . LruCache 工作机制 :

① 获取数据时 :

  • 有缓存 : 如果 LinkedHashMap 缓存中存在该 key 对应的数据 , 那么直接返回该数据 , 并且将该数据放到队头 ;
  • 没有缓存 : 如果 LinkedHashMap 缓存中不存在该 key 对应的数据 , 那么需要创建该数据 , 并插入到 LinkedHashMap 中 , 并且返回该数据 ;

② 插入数据处理 :

  • 缓存没有满 : 向 LinkedHashMap 插入数据 , 如果缓存没有满 , 直接将该数据插入到队头 ;
  • 缓存满了 : 向 LinkedHashMap 插入数据 , 如果缓存满了, 将队尾的若干数据移除队列 , 然后将新数据插入到队头 ;

Lru 内存 缓存 , Disk 磁盘缓存参考 : JakeWharton/DiskLruCache

三、LruCache 常用操作


1 . 创建 LruCache :

① 指定内存 : 创建 LruCache 时 , 需要指定该缓存的最大内存 , 一般是 APP 可用内存的 1/8 ;

② 实现移除回调方法 : 由于内存紧张 , LruCache 将队尾的数据移除队列 , 会回调 entryRemoved , 可以进行一些用户自定义的处理 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        // 设置的内存 , 一般是 APP 可用内存的 1/8
        LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(lruCacheMemoryByte){
            /**
             * 返回 LruCache 的键和值的大小 , 单位使用用户自定义的单位
             * 默认的实现中 , 返回 1 ; size 是 键值对个数 , 最大的 size 大小是最多键值对个数
             * 键值对条目在 LruCache 中缓存时 , 其大小不能改变
             * @param key
             * @param value
             * @return 返回 LruCache<String, Bitmap> 的值 , 即 Bitmap 占用内存
             */
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }

            /**
             * 从 LruCache 缓存移除 Bitmap 时会回调该方法
             * @param evicted
             * @param key
             * @param oldValue
             * @param newValue
             */
            @Override
            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
                                        Bitmap newValue) {
                super.entryRemoved(evicted, key, oldValue, newValue);
                oldValue.recycle();
            }
        };

2 . LruCache 操作 :

① 存放数据 : mLruCache.put(key, value) ;

② 取出数据 : mLruCache.get(key) ;

③ 清除所有缓存数据 : mLruCache.evictAll() ;

四、LruCache 工具类


LruCache 缓存 Bitmap 工具类 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package kim.hsl.bm.utils;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;

/**
 * Bitmap 内存缓存
 * 单纯使用 LruCache 缓存图片到内存中
 */
public class BitmapLruCache {
    private static final String TAG = "BitmapMemoryCache";

    /**
     * 应用上下文对象
     */
    private Context mContext;

    /**
     * 缓存图片的 LruCache
     */
    private LruCache<String, Bitmap> mLruCache;

    /**
     * 单例实现
     */
    private static BitmapLruCache INSTANCE;
    private BitmapLruCache(){}
    public static BitmapLruCache getInstance(){
        if(INSTANCE == null){
            INSTANCE = new BitmapLruCache();
        }
        return INSTANCE;
    }

    /**
     * 使用时初始化
     * @param context
     */
    public void init(Context context){
        // 初始化内存缓存
        initLruCache(context);
    }

    /**
     * 不使用时释放
     */
    public void release(){
    }

    private void initLruCache(Context context){
        // 为成员变量赋值
        this.mContext = context;
        // 获取 Activity 管理器
        ActivityManager activityManager = (ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE);
        // 获取应用可用的最大内存
        int maxMemory = activityManager.getMemoryClass();
        // 获取的 maxMemory 单位是 MB , 将其转为字节 , 除以 8
        int lruCacheMemoryByte = maxMemory / 8 * 1024 * 1024;

        // 设置的内存 , 一般是 APP 可用内存的 1/8
        mLruCache = new LruCache<String, Bitmap>(lruCacheMemoryByte){
            /**
             * 返回 LruCache 的键和值的大小 , 单位使用用户自定义的单位
             * 默认的实现中 , 返回 1 ; size 是 键值对个数 , 最大的 size 大小是最多键值对个数
             * 键值对条目在 LruCache 中缓存时 , 其大小不能改变
             * @param key
             * @param value
             * @return 返回 LruCache<String, Bitmap> 的值 , 即 Bitmap 占用内存
             */
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }

            /**
             * 从 LruCache 缓存移除 Bitmap 时会回调该方法
             * @param evicted
             * @param key
             * @param oldValue
             * @param newValue
             */
            @Override
            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
                                        Bitmap newValue) {
                super.entryRemoved(evicted, key, oldValue, newValue);
                oldValue.recycle();
            }
        };
    }


    /*
        下面的 3 个方法是提供给用户用于操作 LruCache 的接口
     */

    /**
     * 将键值对放入 LruCache 中
     * @param key
     * @param value
     */
    public void putBitmapToLruCache(String key, Bitmap value){
        mLruCache.put(key, value);
    }

    /**
     * 从 LruCache 中获取 Bitmap 对象
     * @param key
     * @return
     */
    public Bitmap getBitmapFromLruCache(String key){
        return mLruCache.get(key);
    }

    /**
     * 清除 LruCache 缓存
     */
    public void clearLruCache(){
        mLruCache.evictAll();
    }

}

五、源码及资源下载

源码及资源下载地址 :

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
实测对比!扣子空间播客功能完爆 NotebookLM,覆盖场景更大
实测对比!扣子空间播客功能完爆 NotebookLM,覆盖场景更大,InfoQ,4分钟
深度学习与Python
2025/06/08
840
实测对比!扣子空间播客功能完爆 NotebookLM,覆盖场景更大
一分钟!教你用deepseek+coze打造金枪大叔智能体
好比《三国演义》里刘备有诸葛亮,你也需要一个懂策略的军师。直接告诉DeepSeek:"我要实现一个网名为金枪大叔(本名 岳华平 ,是一位广告导演和策划人,因其出色的广告创意和营销策略而广为人知)的智能体,请帮我写一份提示词"
一臻AI
2025/06/09
1490
一分钟!教你用deepseek+coze打造金枪大叔智能体
扣子空间能战否?我看行~
最近扣子推出了新模块:扣子空间,功能和前段时间刷屏的Manus类似,就是帮你一步到位完成任务。
zhanyd
2025/04/22
1780
扣子空间能战否?我看行~
探秘 AI Agent 之 Coze 智能体:从简介到搭建全攻略(4/30)
Coze 智能体是基于机器学习和自然语言处理技术的软件实体,它在人工智能领域扮演着重要的角色,能够像一个智能助手一样,通过与外界环境进行交互学习,进而执行各种各样的任务。
正在走向自律
2024/12/18
11.4K0
探秘 AI Agent 之 Coze 智能体:从简介到搭建全攻略(4/30)
探秘 AI Agent 之 Coze 智能体:插件创建与使用(7/30)
摘要:Coze 智能体作为新一代 AI 应用开发平台,其插件功能发挥着至关重要的作用。本文详细阐述了 Coze 智能体插件的多方面内容。首先介绍平台特点及插件重要性,插件能通过调用外部 API 扩展智能体能力。接着分析其功能扩展优势及与其他功能协同性,在内容创作、数据分析等多领域有广泛应用场景。文中细致讲解了插件创建步骤,从准备工作到具体流程,包括配置信息、设置参数及测试发布等。还说明了插件使用方法,如添加到智能体、结合工作流运用及多插件协同案例。通过不同场景实战案例展示其价值,并分享常见问题解决办法。最后探讨行业趋势,展望插件未来功能拓展方向,为读者深入理解和运用 Coze 智能体插件提供全面指导。
正在走向自律
2024/12/18
2.3K0
探秘 AI Agent 之 Coze 智能体:插件创建与使用(7/30)
扣子空间+无限 MCP 服务=通用 Agent 王炸!
在扣子空间用户仅需提供 “一句话指令“ 即可实现任务的自主思考、规划与执行,类似 Manus 定位通用型 Agent。
陈宇明
2025/04/27
3730
扣子空间+无限 MCP 服务=通用 Agent 王炸!
​5G技术生态为智慧旅游提供全面支撑 | 数字文旅周报29期(9.9-9.15)
5G技术生态为智慧旅游提供全面支撑 9月11日,第三届四川旅游新媒体营销大会在自贡举行。作为本次活动的配套活动之一,2019四川旅游新媒体展同时开展,中国联通展出的智慧城市、5G应用等吸引了众多参会嘉宾驻足参观。 四川联通5G创新中心总经理刘伟表示,5G时代的到来,是以5G为引领的一系列信息技术的综合,通过5G基础网络的建设,更多的应用场景将会出现,满足人们更多需求。 旅游新媒体展中国联通智慧文旅展区展示了各垂直行业智能化应用的最新成果,打造覆盖旅游管理部门、涉旅企业及旅行者的旅游信息化系列产品
腾讯文旅
2020/06/17
7100
探秘 AI Agent 之 Coze 智能体:工作流模式(6/30)
摘要:在人工智能领域,随着大模型技术的迅猛发展,智能体的能力得到了极大提升。然而,现实世界中的工作任务往往复杂多样,仅依靠单次大模型调用已难以满足需求。许多任务需要多个步骤、多种技术的协同配合才能完成,例如从数据收集到分析再到决策的过程,或者从用户需求理解到多轮交互并最终提供满意解决方案的服务场景。工作流模式应运而生,它将复杂任务分解为一系列有序的子任务,通过合理组织和协调不同的组件与操作,实现任务的高效处理。这种模式在当前的 AI 应用开发中具有至关重要的意义,它不仅提高了任务处理的准确性和可靠性,还增强了智能体应对复杂多变环境的能力。
正在走向自律
2024/12/18
5.9K2
探秘 AI Agent 之 Coze 智能体:工作流模式(6/30)
【愚公系列】《高效使用DeepSeek》014-行程计划
📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主!
愚公搬代码
2025/03/22
1360
终于有个不瞎编的旅游AI了。
我打开飞猪,才看到,他们偷摸更新了,在左上角放了一个问一问的入口,但是点进去要邀请码,于是我又拜托阿里的朋友,帮我搞了一个邀请码,才顺利进去。
数字生命卡兹克
2025/04/26
660
终于有个不瞎编的旅游AI了。
【愚公系列】《高效使用DeepSeek》026-旅行攻略生成
📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主!
愚公搬代码
2025/04/01
2610
AI智能体|老板以为我在加班做Excel图表,其实是DeepSeek+扣子(Coze)在帮我!
小王是某电商平台的运营专员,每周一的工作就是整理上周的销售数据,制作可视化报表给领导汇报。
一臻AI
2025/04/28
5261
AI智能体|老板以为我在加班做Excel图表,其实是DeepSeek+扣子(Coze)在帮我!
Manus:开启AI智能体的新时代
文章摘要:Manus 是由北京蝴蝶效应科技有限公司的 Monica 团队发布的全球首款通用型 AI 智能体产品,于 2025 年 3 月 6 日凌晨问世,引发科技界和资本市场轰动。Manus源自拉丁语 “Mens et Manus”,寓意 “手脑并用”,将大模型逻辑推理转化为实际生产力,区别于传统仅提供建议或简单回答的 AI 助手,能独立思考、规划并执行复杂任务,交付完整成果。其研发基于 AI 行业发展背景,克服多模态交互、多语言支持等技术难题推出,采用多智能体架构,具备独立思考与规划、强大工具调用能力、优异性能表现等技术特点,在办公、金融、教育、医疗等多领域有广泛应用前景,与同类产品如 DeepSeek、ChatGPT 等对比有独特优势,但也都面临着技术可靠性、商业模式可持续性、市场炒作等挑战与争议,未来有望通过技术迭代、商业化拓展、开源与合作等实现更大发展。
正在走向自律
2025/03/08
9542
Manus:开启AI智能体的新时代
扣子(Coze):构建智能助手并嵌入个人网站的新选择
所以,综合这些原因,我放弃了在个人网站中使用 MaxKB,但是我并不否认它是一个很好的产品;只是对于我想集成一个智能助手到个人网站的这个需求而言,他并不是最好的选择;
MinChess
2024/11/13
2.5K0
扣子(Coze):构建智能助手并嵌入个人网站的新选择
最全NLP反作弊攻略,从马蜂窝注水事件说起
10月21日,朋友圈被一篇名为《估值175亿的旅游独角兽,是一座僵尸和水军构成的鬼城?》的文章刷屏。文章作者小声比比指控在线旅游网站马蜂窝存在点评大量造假的情况,包括从其他网站如大众点评、携程等抓取相关点评,及通过水军撰写虚拟点评。
大数据文摘
2018/12/14
1.4K0
产业篇 | 文旅产业结构再升级,五一期间实现高质量恢复与发展
编者按:刚刚过去的“五一”旅游市场,成为疫情以来的第一个旅游高峰,实现国内旅游收入475.6亿元。虽然尚未恢复到去年同期水平,但已经显示出强劲的反弹势头,同时线上线下的一体化融合发展成为共识,文旅产业进入了新一轮供给侧结构调整阶段,正以优质精品产品服务迎接产业复苏。 4月27日,中央宣传部、文化和旅游部召开2020年“五一”假期旅游景区开放管理工作电视电话会议指出,2020年的“五一”假期是我国进入常态化疫情防控阶段后的首个旅游小长假,要切实做好旅游景区疫情防控和安全有序开放工作,把旅游景区开放管
腾讯文旅
2020/06/17
6050
原来,AI也有「搜商」高低的差别?
五一假期刚过,相信不少人已经在朋友圈的「人海直播」中深刻体会到了一个真理:出门旅游,光靠一腔热情远远不够。
机器之心
2025/05/09
990
原来,AI也有「搜商」高低的差别?
LLMOps实战(二):揭秘自注意力机制:从原理到高效应用技巧
自注意力机制(Self-Attention)是Transformer模型的核心组件,其本质是让序列中的每个元素(如句子中的单词)能够动态捕捉与其他元素的相关性,了解自注意力机制了原理,在之后的提示词优化,文本向量化调试都会有所帮助。
范赟鹏
2025/03/26
1.1K0
我的十一假期旅行,完全被人工智能操控了。
但这次国庆假期的旅行,我复盘后发现,从选择目的地、制定旅行计划、预定机票酒店等等,我都被 AI 操控了,而且我一点儿都不生气。
HyperAI超神经
2019/12/01
4530
中国智慧文旅产业峰会举行 文化和旅游将走向智能化创新之路 | 每周文旅资讯精选(2.25-3.3)
中国智慧文旅产业峰会举行 文化和旅游将走向智能化创新之路 3月1日,中国智慧文旅产业峰会正式举行,本次峰会上,众多文旅产业相关领导、专家共同探讨在全域旅游快速发展以及文旅融合的形势下,信息技术如何提升产业价值、提高服务水平。 中国联合网络通信集团有限公司副总经理梁宝俊 中国联合网络通信集团有限公司副总经理梁宝俊在会上指出,文化和旅游是改善民生持续增强人民获得感的幸福产业,未来将立足贵州、面向全国,更好地走出一条文旅产业的信息化、智能化创新之路。 目前中国联通已在贵州完成了“云上贵州·智慧
腾讯文旅
2020/06/17
5500
推荐阅读
相关推荐
实测对比!扣子空间播客功能完爆 NotebookLM,覆盖场景更大
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档