Android的DiskLruCache硬盘缓存技术

之前记着LruCache我们从网络下载好的图片现存入到内存,下次直接从内存读取整体读取速度都变快了,但是我们退出应用下次再进来相同的图片是否可以不用从网络读取,所以DiskLruCache就是做这方面的工作。

由于DiskLruCache不是Android官方提供的类,所以我们需要导入该类,可以从Github上搜出来导入即可。

DiskLruCache.open(file, BitmapUtil.getVersion(this), 1, 10 * 1024 * 1024);

通过上面的代码我们就可以初始化一个DiskLruCache对象,其中需要传入四个参数分别是 SD缓存的目录、app版本号、对应文件要缓存的数量、缓存空间大小。

1.设置缓存目录

public static File getDiskCacheDir(Context context, String uniqueName) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }
        return new File(cachePath + File.separator + uniqueName);
    }

如果SD可用则目录就会存放到/sdcard/Android/data/..包名../cache这个路径下,否则就存放到/data/data/..包名../cache这个目录下。

2.读取版本号

public static int getVersion(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 0;
    }

做好这两步工作之后我们就可以初始化一个DisLruCache对象了。

private void initDisLrucache() {
        File file = BitmapUtil.getDiskCacheDir(this, "bitmap");
        try {
            mDiskLruCache = DiskLruCache.open(file, BitmapUtil.getVersion(this), 1, 10 * 1024 * 1024);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

经过初始化之后我们就可以开始使用DisLruCache将下载好的图片存入到SD目录下。

3.下载图片并缓存起来
因为我们不能直接把图片地址作为key直接存放到SD卡 所以需要对url简单的MD5加密当做key值。

public static String hashKeyForDisk(String key) {
        String cacheKey;
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(key.getBytes());
            cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
        }
        return cacheKey;
    }

    private static String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

而DisLruCache是使用Editor这个类通过edit完成的。

String url = "https://img-my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
            String key = BitmapUtil.hashKeyForDisk(url);
            try {
                DiskLruCache.Editor editor = mDiskLruCache.edit(key);
                if (editor != null) {
                    if (loadImage(url, editor.newOutputStream(0))) {
                        editor.commit();
                    } else {
                        editor.abort();
                    }
                }
                mDiskLruCache.flush();// 更新缓存日志
            } catch (IOException e) {
                e.printStackTrace();
            }

其中的mDiskLruCache.flush()这个方法不是每次都要调用,因为这个方法是用来同步日志用的,所以可以在Activity的onPause方法中调用一次就好。

4.读取缓存图片
读取缓存可直接调取DiskLrucache的get方法即可,可是get放回的是Snapshot对象我们需要再次转换成InputStream,就可以调用BitmapFactory.decodeStram方法获取Bitmap对象从而显示在ImageView上。

String url = "https://img-my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
                String key = BitmapUtil.hashKeyForDisk(url);
                try {
                    DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
                    if (snapshot != null) {
                        InputStream is = snapshot.getInputStream(0);
                        Bitmap bitmap = BitmapFactory.decodeStream(is);
                        mImageView.setImageBitmap(bitmap);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

这样我们就完成了写入和读取功能,DisLruCache每次操作都会往journal日志写入日志。除了写入和读取外 还有移除功能。

5.额外功能
移除功能:

try {  
    String imageUrl = "https://img-my.csdn.net/uploads/201309/01/1378037235_7476.jpg";    
    String key = hashKeyForDisk(imageUrl);    
    mDiskLruCache.remove(key);  
} catch (IOException e) {  
    e.printStackTrace();  
}  

计算缓存大小和删除缓存空间
size():这个方法会返回当前缓存路径下所有缓存数据的总字节数,以byte为单位
delete():这个方法用于将所有的缓存数据全部删除
这两个方法就可以处理app中常见的清除缓存的功能。

参考:Android DiskLruCache完全解析,硬盘缓存的最佳方案

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值