文章目录

  • 一、Bitmap 内存缓存策略
  • 二、LruCache 内存缓存
  • 三、LruCache 常用操作
  • 四、LruCache 工具类
  • 五、源码及资源下载



官方参考 : 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 3 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 集合 ;

// 这是定义杂 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 , 可以进行一些用户自定义的处理 ;

        // 设置的内存 , 一般是 APP 可用内存的 1/8        LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(lruCacheMemoryByte){            /**             * 返回 LruCache 的键和值的大小 , 单位使用用户自定义的单位             * 默认的实现中 , 返回 1 ; size 是 键值对个数 , 最大的 size 大小是最多键值对个数             * 键值对条目在 LruCache 中缓存时 , 其大小不能改变             * @param key             * @param value             * @return 返回 LruCache 的值 , 即 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 工具类 :

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 的值 , 即 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();    }}




五、源码及资源下载



源码及资源下载地址 :

  • ① GitHub 工程地址 : BitmapMemory

  • ② BitmapLruCache.java 工具类地址 : BitmapLruCache.java

更多相关文章

  1. android仿网易云音乐引导页、仿书旗小说Flutter版、ViewPager切
  2. Handler和Message的使用之三
  3. android下变态的串口通讯
  4. Android学习之期末复习重点整理
  5. Android(安卓)使用AsyncTask后台线程实现数据异步刷新
  6. BitRaser for Mobile iOS和Android移动设备的安全数据擦除软件
  7. Android(安卓)Bmob后端云—数据库、服务器!
  8. Android(安卓)-中毒
  9. mybatisplus的坑 insert标签insert into select无参数问题的解决

随机推荐

  1. android之wifi移植全过程(二)
  2. Android SystemProperties (java) 权限问
  3. LPAPlayer (Low Power Audio Player) in
  4. android在代码里设置button或者textView
  5. Android 推荐 开源项目
  6. Android对话框 (AlertDialog & ProgressD
  7. Android(安卓)gradle配置
  8. Android直播开发之旅(9):OkCamera,Android
  9. Android 网络框架 Retrofit 源码解析
  10. 2019最新《Android开发全套学习教程》