文章目录

  • 一、Google 官方 Bitmap 相关示例参考
  • 二、磁盘缓存类 DiskLruCache
  • 三、磁盘缓存初始化
  • 四、存储数据到磁盘缓存中
  • 五、从磁盘缓存中读取数据
  • 六、 Android 10 文件访问
  • 七、代码示例
    • 1、二级缓存代码示例
    • 2、调用工具类代码示例
  • 八、源码及资源下载



在上一篇博客 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 内存复用 | 弱引用 | 引用队列 | 针对不同 Android 版本开发不同的 Bitmap 复用策略 | 工具类代码 ) 中 , 使用 LruCache 缓存内存数据 , 同时兼顾 Bitmap 内存复用 , 使用弱引用 Bitmap 对象集合维护 Bitmap 复用池 , 确保该复用池中的 Bitmap 对象寿命都很短 , 每次 GC 都会清理一遍复用池 ; 当 LruCache 中的数据由于最近不常使用 , 从 LruCache 内存中移除 , 此时将其放入 Bitmap 复用池中 , 将该 Bitmap 对象纳入复用机制管理 ;





一、Google 官方 Bitmap 相关示例参考



Google 官方相关示例参考 :


① Android 官方示例 : https://github.com/android

② Android 图形示例 : android/graphics-samples

③ Bitmap 展示 Module : DisplayingBitmaps

④ 官方示例中的硬盘缓存类 : DiskLruCache.java


在 DisplayingBitmaps 示例中 , Google 官方展示了在应用中如何使用 Bitmap ;





二、磁盘缓存类 DiskLruCache



推荐使用 JakeWharton 的开源库 DiskLruCache , 点击上述连接即可进入工程界面 ;


点击 GitHub 界面右侧的 Release 界面 , 下载发布的 Release 版本 , 尽量不要直接下载开发中的最新版本 ;

【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )_第1张图片

这里选择下载最新的 Release 版本 , disklrucache-2.0.2 版本 , 点击此处直接调转到该界面 ;

【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )_第2张图片

下载完毕后 , 打开压缩包 , 直接将这三个文件 , 拷贝到项目中 ;





三、磁盘缓存初始化



首先声明 DiskLruCache 磁盘 LRU 缓存类 ,然后初始化 DiskLruCache 类 , 主要是设置磁盘缓存目录 , 应用版本号 , 每个 Key 可以对应多个文件个数 , 磁盘大小

    /**     * 磁盘缓存     */    private DiskLruCache mDiskLruCache;    /**     * 初始化磁盘缓存     * @param diskDirectory     */    private void initDiskLruCache(String diskDirectory){        try {            /*                初始化内存缓存                需要传入内存缓存目录文件                APP 版本                缓存值的个数                缓存大小 , 单位字节 , 这个最重要             */            mDiskLruCache = DiskLruCache.open(                    new File(diskDirectory),                    BuildConfig.VERSION_CODE,                    1,                    8 * 1024 * 10024            );        } catch (IOException e) {            e.printStackTrace();        }    }




四、存储数据到磁盘缓存中



1 . 从 DiskLruCache 中获取 Bitmap 流程 :


① 获取快照 : 通过 key 获取 DiskLruCache.Snapshot 对象 ;

snapshot = mDiskLruCache.get(key);

② 打开编辑器 : 打开 DiskLruCache.Editor , 该用法与 SharedPreference 用法类似 ;

DiskLruCache.Editor editor = mDiskLruCache.edit(key);

③ 获取输出流 : 从 DiskLruCache.Editor 对象中获取出输出流 , 这里的 0 表示获取该 key 对应的第 0 个文件 , 每个 Key 可以对应多个文件 , 这个值是创建 DiskLruCache 时传入的 valueCount 参数 ;

outputStream = editor.newOutputStream(0);

④ 写出 Bitmap 对象到文件中 :

bitmap.compress(Bitmap.CompressFormat.JPEG, 0, outputStream);

⑤ 编辑器提交数据 :

editor.commit();


2 . 代码示例 :

    /**     * 将 Bitmap 放入 磁盘缓存 中     * @param key     * @param bitmap     */    public void putBitmapToDisk(String key, Bitmap bitmap){        DiskLruCache.Snapshot snapshot = null;        OutputStream outputStream = null;        try {            snapshot = mDiskLruCache.get(key);            // 如果缓存中有对应 key 键值的文件 , 不进行任何处理            if(snapshot != null) {                // 该用法与 SharedPreference 用法类似                DiskLruCache.Editor editor = mDiskLruCache.edit(key);                if(editor != null){                    // 这里的 0 表示获取该 key 对应的第 0 个文件                    // 每个 可以 可以对应多个文件 , 这个值是创建 DiskLruCache 时传入的 valueCount 参数                    outputStream = editor.newOutputStream(0);                    // 写出 Bitmap 对象到文件中                    bitmap.compress(Bitmap.CompressFormat.JPEG, 0, outputStream);                    // 该用法与 SharedPreference 用法类似                    editor.commit();                }            }        } catch (IOException e) {            e.printStackTrace();        }finally {            if(snapshot != null) {                snapshot.close();            }            if(outputStream != null){                try {                    outputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }




五、从磁盘缓存中读取数据



1 . 从 DiskLruCache 中获取 Bitmap 流程 :


① 获取快照 : 通过 key 获取 DiskLruCache.Snapshot 对象 ;

snapshot = mDiskLruCache.get(key);

② 打开编辑器 : 打开 DiskLruCache.Editor , 该用法与 SharedPreference 用法类似 ;

DiskLruCache.Editor editor = mDiskLruCache.edit(key);

③ 获取输入流 : 从 DiskLruCache.Editor 对象中获取出输入流 , 这里的 0 表示获取该 key 对应的第 0 个文件 , 每个 Key 可以对应多个文件 , 这个值是创建 DiskLruCache 时传入的 valueCount 参数 ;

inputStream = editor.newInputStream(0);

④ 从输入流中读取数据到 Bitmap 中 : 这里用到了 Bitmap 内存复用机制 , 另外从磁盘读取数据后 , 向内存缓存一份 ;

                    BitmapFactory.Options options = new BitmapFactory.Options();                    options.inMutable = true;                    options.inBitmap = inBitmap;                    // 写出 Bitmap 对象到文件中                    bitmap = BitmapFactory.decodeStream(inputStream, null, options);                                        if(bitmap != null){                        // 从磁盘读取后 , 先缓存到内存中                        mLruCache.put(key, bitmap);                    }

⑤ 编辑器提交数据 :

editor.commit();


2 . 代码示例 :

    /**     * 从 磁盘缓存 中取出 Bitmap 对象     * @param key       键值     * @param inBitmap 复用 Bitmap 内存     * @return     */    public Bitmap getBitmapFromDisk(String key, Bitmap inBitmap){        Bitmap bitmap = null;        DiskLruCache.Snapshot snapshot = null;        InputStream inputStream = null;        try {            snapshot = mDiskLruCache.get(key);            // 如果缓存中有对应 key 键值的文件 , 不进行任何处理            if(snapshot != null) {                // 该用法与 SharedPreference 用法类似                DiskLruCache.Editor editor = mDiskLruCache.edit(key);                if(editor != null){                    // 这里的 0 表示获取该 key 对应的第 0 个文件                    // 每个 可以 可以对应多个文件 , 这个值是创建 DiskLruCache 时传入的 valueCount 参数                    inputStream = editor.newInputStream(0);                    BitmapFactory.Options options = new BitmapFactory.Options();                    options.inMutable = true;                    options.inBitmap = inBitmap;                    // 写出 Bitmap 对象到文件中                    bitmap = BitmapFactory.decodeStream(inputStream, null, options);                    if(bitmap != null){                        // 从磁盘读取后 , 先缓存到内存中                        mLruCache.put(key, bitmap);                    }                    // 该用法与 SharedPreference 用法类似                    editor.commit();                }            }        } catch (IOException e) {            e.printStackTrace();        }finally {            if(snapshot != null) {                snapshot.close();            }            if(inputStream != null){                try {                    inputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return bitmap;    }




六、 Android 10 文件访问



文件存储相关官方参考资料 :

  • Android 11 中的存储机制更新
  • Android storage use cases and best practices
  • 应用数据和文件

参考之前的博客 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 ) 三、 Android 10 文件访问 有涉及到在 Android 10 系统中访问 SD 卡 ;





七、代码示例





1、二级缓存代码示例



磁盘内存二级缓存代码示例 :

package kim.hsl.bm.utils;import android.app.ActivityManager;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Build;import android.util.LruCache;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.ref.Reference;import java.lang.ref.ReferenceQueue;import java.lang.ref.WeakReference;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import kim.hsl.bm.BuildConfig;import kim.hsl.bm.diskcache.DiskLruCache;/** * Bitmap 内存缓存 * 在将图片缓存到 LruCache 内存中基础上 , * 将从 LruCache 中移除的最近没有使用的 Bitmap 对象的内存复用 * 这样能最大限度减少内存抖动 */public class BitmapDiskLruCacheMemoryReuse {    private static final String TAG = "BitmapMemoryCache";    /**     * 应用上下文对象     */    private Context mContext;    /**     * 缓存图片的 LruCache     */    private LruCache<String, Bitmap> mLruCache;    /**     * 磁盘缓存     */    private DiskLruCache mDiskLruCache;    /**     * Bitmap 复用池     * 使用 inBitmap 复用选项     * 需要获取图片时 , 优先从 Bitmap 复用池中查找     * 这里使用弱引用保存该 Bitmap , 每次 GC 时都会回收该 Bitmap     * 创建一个线程安全的 HashSet , 其中的元素是 Bitmap 弱引用     *     * 该 Bitmap 复用池的作用是 , 假如 Bitmap 对象长时间不使用 , 就会从内存缓存中移除     *     * Bitmap 回收策略 :     * 3.0 以下系统中 , Bitmap 内存在 Native 层     * 3.0 以上系统中 , Bitmap 内存在 Java 层     * 8.0 及以上的系统中 , Bitmap 内存在 Native 层     *     * 因此这里需要处理 Bitmap 内存在 Native 层的情况 , 监控到 Java 层的弱引用被释放了     * 需要调用 Bitmap 对象的 recycle 方法 , 释放 Native 层的内存     *     * 需要使用引用队列监控弱引用的释放情况     */    Set<WeakReference<Bitmap>> bitmapReusePool;    /**     * 引用队列 , 用于监控 Set> bitmapReusePool 的内存是否被回收     * 需要维护一个线程 , 不断尝试从该引用队列中获取引用     *     */    private ReferenceQueue<Bitmap> referenceQueue;    /**     * 监控 Set> bitmapReusePool 的内存是否被回收 ,     * 调用 ReferenceQueue referenceQueue 的 remove 方法 ,     * 查看是否存在被回收的弱引用 , 如果存在 , 直接回收该弱引用对应的 Bitmap 对象     */    private Thread referenceQueueMonitorThread;    /**     * 是否持续监控引用队列 ReferenceQueue     */    private boolean isMonitorReferenceQueue = true;    /**     * 单例实现     */    private static BitmapDiskLruCacheMemoryReuse INSTANCE;    private BitmapDiskLruCacheMemoryReuse(){}    public static BitmapDiskLruCacheMemoryReuse getInstance(){        if(INSTANCE == null){            INSTANCE = new BitmapDiskLruCacheMemoryReuse();        }        return INSTANCE;    }    /**     * 使用时初始化     * @param context     */    public void init(Context context, String diskDirectory){        // 初始化内存缓存        initLruCache(context);        // 初始化弱引用队列        initBitmapReusePool();        // 初始化磁盘缓存        initDiskLruCache(diskDirectory);    }    /**     * 不使用时释放     */    public void release(){        isMonitorReferenceQueue = false;    }    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) {                // 如果使用的是复用的 Bitmap 对象 , 其占用内存大小是之前的图像分配的内存大小                // 大于等于当前图像的内存占用大小                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                    return value.getAllocationByteCount();                }                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);                /*                    如果从 LruCache 内存缓存中移除的 Bitmap 是可变的                    才能被复用 , 否则只能回收该 Bitmap 对象                    Bitmap 回收策略 :                    3.0 以下系统中 , Bitmap 内存在 Native 层                    3.0 以上系统中 , Bitmap 内存在 Java 层                    8.0 及以上的系统中 , Bitmap 内存在 Native 层                    因此这里需要处理 Bitmap 内存在 Native 层的情况 , 监控到 Java 层的弱引用被释放了                    需要调用 Bitmap 对象的 recycle 方法 , 释放 Native 层的内存                 */                if(oldValue.isMutable()){   // 可以被复用                    // 将其放入弱引用中 , 每次 GC 启动后 , 如果该弱引用没有被使用 , 都会被回收                    bitmapReusePool.add(new WeakReference<Bitmap>(oldValue, referenceQueue));                }else{  // 不可被复用 , 直接回收                    oldValue.recycle();                }            }        };    }    /**     * 初始化引用队列     */    private void initBitmapReusePool(){        // 创建一个线程安全的 HashSet , 其中的元素是 Bitmap 弱引用        bitmapReusePool = Collections.synchronizedSet(new HashSet<WeakReference<Bitmap>>());        // 引用队列 , 当弱引用被 GC 扫描后 , 需要回收 , 会将该弱引用放入队列        // 一直不断的尝试从该引用队列中获取数据 , 如果获取到数据 , 就要回收该对象        referenceQueue = new ReferenceQueue<>();        // 定义监控线程        referenceQueueMonitorThread = new Thread(){            @Override            public void run() {                while (isMonitorReferenceQueue){                    try {                        Reference<Bitmap> reference = (Reference<Bitmap>) referenceQueue.remove();                        Bitmap bitmap = reference.get();                        // 不为空 , 且没有被回收 , 回收 Bitmap 内存                        if(bitmap != null && !bitmap.isRecycled()){                            bitmap.recycle();                        }                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        };        // 启动引用队列监控线程        referenceQueueMonitorThread.start();    }    /**     * 初始化磁盘缓存     * @param diskDirectory     */    private void initDiskLruCache(String diskDirectory){        try {            /*                初始化内存缓存                需要传入内存缓存目录文件                APP 版本                缓存值的个数                缓存大小 , 单位字节 , 这个最重要             */            mDiskLruCache = DiskLruCache.open(                    new File(diskDirectory),                    BuildConfig.VERSION_CODE,                    1,                    8 * 1024 * 10024            );        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 获取一个可以被复用的 Bitmap 对象     *     * 与 BitmapFactory 配合使用 :     *     * Android 4.4 以后的 Bitmap 复用情况 :     * 在 KITKAT ( Android 4.4 , 19 平台 ) 以后的代码中 ,     * 只要被解码生成的 Bitmap 对象的字节大小 ( 缩放后的 )     * 小于等于 inBitmap 的字节大小 , 就可以复用成功 ;     *     * Android 4.4 之前的 Bitmap 复用情况 : ( 比较苛刻 )     * 在 KITKAT 之前的代码中 , 被解码的图像必须是     *  - JPEG 或 PNG 格式 ,     *  - 并且 图像大小必须是相等的 ,     *  - inssampleSize 设置为 1 ,     * 才能复用成功 ;     * 另外被复用的图像的 像素格式 Config ( 如 RGB_565 ) 会覆盖设置的 inPreferredConfig 参数     *     * @param width     * @param height     * @param inSampleSize     * @return     */    public Bitmap getReuseBitmap(int width,int height,int inSampleSize){        // Android 2.3.3(API 级别 10)及以下的版本中 , 使用 Bitmap 对象的 recycle 方法回收内存        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1){            // 如果 API 级别小于等于 10 , 不启用 Bitmap 内存复用机制 , 返回 null 即可            return null;        }        // 获取准备复用的 Bitmap , 之后设置到 Options 中        Bitmap inBitmap = null;        // 使用迭代器遍历该 Set 集合 , 如果遍历中涉及到删除 , 就要使用迭代器遍历        Iterator<WeakReference<Bitmap>> iterator = bitmapReusePool.iterator();        //迭代查找符合复用条件的Bitmap        while (iterator.hasNext()){            // 循环遍历 Bitmap 对象            Bitmap bitmap = iterator.next().get();            if (bitmap != null){                /*                    检查该 Bitmap 对象是否可以达到复用要求 ,                    如果达到复用要求 , 就取出这个 Bitmap 对象 , 并将其从队列中移除                 */                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2){                    /*                        Android 4.4(API 级别 19)以下的版本 : 在 Android 4.4(API 级别 19) 之前的代码中 ,                        复用的前提是必须同时满足以下 3 个条件 :                            1. 被解码的图像必须是 JPEG 或 PNG 格式                            2. 被复用的图像宽高必须等于 解码后的图像宽高                            3. 解码图像的 BitmapFactory.Options.inSampleSize 设置为 1 , 也就是不能缩放                        才能复用成功 , 另外被复用的图像的像素格式 Config ( 如 RGB_565 ) 会覆盖设置的                        BitmapFactory.Options.inPreferredConfig 参数 ;                     */                    if(bitmap.getWidth() == width &&                            bitmap.getHeight() == height && //被复用的图像宽高必须等于 解码后的图像宽高                            inSampleSize == 1){// 图像的 BitmapFactory.Options.inSampleSize 设置为 1                        //符合要求                        inBitmap = bitmap;                        iterator.remove();                    }                }else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){                    /*                        在 Android 4.4(API 级别 19)及以上的版本中 ,                        只要被解码后的 Bitmap 对象的字节大小 , 小于等于 inBitmap 的字节大小 , 就可以复用成功 ;                        解码后的乳香可以是缩小后的 , 即 BitmapFactory.Options.inSampleSize 可以大于1 ;                     */                    // 首先要计算图像的内存占用 , 先要计算出图像的宽高 , 如果图像需要缩放 , 计算缩放后的宽高                    if(inSampleSize > 1){                        width = width / inSampleSize ;                        height = height / inSampleSize;                    }                    // 计算内存占用 , 默认 ARGB_8888 格式                    int byteInMemory = width * height * 4;;                    if(bitmap.getConfig() == Bitmap.Config.ARGB_8888){                        // 此时每个像素占 4 字节                        byteInMemory = width * height * 4;                    }else if(bitmap.getConfig() == Bitmap.Config.RGB_565){                        // 此时每个像素占 2 字节                        byteInMemory = width * height * 2;                    }                    // 如果解码后的图片内存小于等于被复用的内存大小 , 可以复用                    if(byteInMemory <= bitmap.getAllocationByteCount()){                        //符合要求                        inBitmap = bitmap;                        iterator.remove();                    }                }            }else if( bitmap == null ){                // 如果 bitmap 为空 , 直接从复用 Bitmap 集合中移除                iterator.remove();            }        }        return inBitmap;    }    /*        下面的 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();    }    /*        下面的 2 个方法是提供给用户用于操作 磁盘 的接口     */    /**     * 将 Bitmap 放入 磁盘缓存 中     * @param key     * @param bitmap     */    public void putBitmapToDisk(String key, Bitmap bitmap){        DiskLruCache.Snapshot snapshot = null;        OutputStream outputStream = null;        try {            snapshot = mDiskLruCache.get(key);            // 如果缓存中有对应 key 键值的文件 , 不进行任何处理            if(snapshot != null) {                // 该用法与 SharedPreference 用法类似                DiskLruCache.Editor editor = mDiskLruCache.edit(key);                if(editor != null){                    // 这里的 0 表示获取该 key 对应的第 0 个文件                    // 每个 可以 可以对应多个文件 , 这个值是创建 DiskLruCache 时传入的 valueCount 参数                    outputStream = editor.newOutputStream(0);                    // 写出 Bitmap 对象到文件中                    bitmap.compress(Bitmap.CompressFormat.JPEG, 0, outputStream);                    // 该用法与 SharedPreference 用法类似                    editor.commit();                }            }        } catch (IOException e) {            e.printStackTrace();        }finally {            if(snapshot != null) {                snapshot.close();            }            if(outputStream != null){                try {                    outputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    /**     * 从 磁盘缓存 中取出 Bitmap 对象     * @param key       键值     * @param inBitmap 复用 Bitmap 内存     * @return     */    public Bitmap getBitmapFromDisk(String key, Bitmap inBitmap){        Bitmap bitmap = null;        DiskLruCache.Snapshot snapshot = null;        InputStream inputStream = null;        try {            snapshot = mDiskLruCache.get(key);            // 如果缓存中有对应 key 键值的文件 , 不进行任何处理            if(snapshot != null) {                // 该用法与 SharedPreference 用法类似                DiskLruCache.Editor editor = mDiskLruCache.edit(key);                if(editor != null){                    // 这里的 0 表示获取该 key 对应的第 0 个文件                    // 每个 可以 可以对应多个文件 , 这个值是创建 DiskLruCache 时传入的 valueCount 参数                    inputStream = editor.newInputStream(0);                    BitmapFactory.Options options = new BitmapFactory.Options();                    options.inMutable = true;                    options.inBitmap = inBitmap;                    // 写出 Bitmap 对象到文件中                    bitmap = BitmapFactory.decodeStream(inputStream, null, options);                    if(bitmap != null){                        // 从磁盘读取后 , 先缓存到内存中                        mLruCache.put(key, bitmap);                    }                    // 该用法与 SharedPreference 用法类似                    editor.commit();                }            }        } catch (IOException e) {            e.printStackTrace();        }finally {            if(snapshot != null) {                snapshot.close();            }            if(inputStream != null){                try {                    inputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return bitmap;    }}


2、调用工具类代码示例



   /**     * 图像磁盘内存缓存     */    private void diskMemoryCache(){        // 初始化 LruCache 内存缓存 , 与引用队列 , 一般在 onCreate 方法中初始化        // 这里为了演示 , 放在方法的开头位置        BitmapDiskLruCacheMemoryReuse.getInstance().init(this, Environment.getExternalStorageDirectory() + "/diskCache");        // 1. 第一次尝试从 LruCache 内存中获取 Bitmap 数据        Bitmap bitmap = BitmapDiskLruCacheMemoryReuse.getInstance().                getBitmapFromLruCache(R.drawable.blog + "");        /*            如果从内存中获取 Bitmap 对象失败 , 再次从磁盘中尝试获取该 Bitmap         */        if(bitmap == null){            // 要复用内存的 Bitmap 对象 , 将新的 Bitmap 写入到该 Bitmap 内存中            Bitmap inBitmap = null;            // 尝试获取复用对象            BitmapDiskLruCacheMemoryReuse.getInstance().                    getReuseBitmap(200, 200, 1);            // 2. 第二次尝试从磁盘中获取图片            bitmap = BitmapDiskLruCacheMemoryReuse.getInstance().getBitmapFromDisk(                    R.drawable.blog + "", inBitmap);            // 磁盘中没有找到 , 再次尝试加载该图片            if(bitmap == null) {                // 3. 如果内存, 磁盘都没有获取到 Bitmap, 那么加载指定大小格式的图像                bitmap = BitmapSizeReduce.getResizedBitmap(this, R.drawable.blog,                        200, 200, false, inBitmap);                // 将新的 bitap 放入 LruCache 内存缓存中                BitmapDiskLruCacheMemoryReuse.getInstance().                        putBitmapToLruCache(R.drawable.blog + "", bitmap);            }        }    }




八、源码及资源下载



源码及资源下载地址 :

  • ① GitHub 工程地址 : BitmapMemory

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

更多相关文章

  1. Android之DiskLruCache(缓存工具)
  2. 【Android Training - Performance】 - 管理应用的内存
  3. Android内存泄漏分析
  4. Android获得全局进程信息以及进程使用的内存情况
  5. Android获取 应用程序大小,数据大小,缓存大小
  6. Android查看内存和CPU~
  7. Android 性能优化二 内存优化

随机推荐

  1. Android的线程使用来更新UI----Thread、H
  2. Android基础入门教程——2.2.1 LinearLay
  3. Android里解析AndroidManifest.xml的java
  4. Android中短信的读取与拦截
  5. Fastboot使用详解
  6. Activity横竖屏切换时的UI处理
  7. android 文件系统结构及其引导
  8. 关于Android中的数据存储
  9. Android(安卓)开发者网站
  10. 文字位于RadioButton后,如何调整间距?