关闭

Glide图片加载神器----官方库wiki说明文档的翻译(缓存与缓存校验)

标签: 缓存图片
1795人阅读 评论(0) 收藏 举报
分类:

上一篇是:Glide图片加载神器—-官方库wiki说明文档的翻译(首页)


缓存校验是一个相对复杂的话题和概念,应该尽量少去考虑。本篇幅将给出一个在Glide中如何生成cache key大致的方案,并且如何让缓存更好的为你工作给一些建议提醒。

Cache Keys:
在Glide中Cache Keys用于DiskCacheStrategy.RESULT 的用途包含四个主要部分:

  1. 从DataFetcher里的getId()方法中返回key的字符串。在你的data model上DataFecher仅仅是调用了toString()作为返回结果,因此如果你提供的是URL那么这个字符串就是URL形式的,也或者是你提供的是文件那字符串就是文件的路径,等等。

  2. 宽高通过调用 override(int, int)方法来设置,或者通过 Target’s getSize()方法提供的默认的宽高。

  3. 通过getId()获取的字符串key,在不同的编码和解码器中用户加载和缓存你的图片。只有编码和解码器才会影响包含了id的检索到的字节。例如,如果你的编码器只是写入一个字节数组到磁盘里,那么这个编码器不会有id,因为它在任何情况下都不会影响数据。(卧槽!!!这段话好难理解, 暂且这么翻译吧, 我也不是很理解, 等以后实际东西写例子了再来更新解释, 姑且大家伙都先蛋疼着,如果有知道意思的, 麻烦底下留言说说,不胜感激啊~~)。

  4. 给每一个加载做签名的操作(具体看底下的cache invalidation缓存校验部分)

所有以上情况的key都是hash值,是为了创建唯一并且安全的文件名用来保存在磁盘中。

Cache Invalidation 缓存校验:
由于文件名是hash钥匙key,因此仅凭特有的url或者文件路径去删除磁盘上的所有缓存文件不是个好方法。问题也是显而易见的,如果只是加载或者缓存了原始图片那是可以的。但是一旦缓存了缩略图亦或是提供了些不同的transformation变换就不行了,在这种情况下每种都会在缓存中生成新的文件,查询和删除一个图片的每种类型的缓存文件版本就变的很困难。
实际上,最好的办法就是当内容数据改变的时候校验一个改变了唯一标识的缓存文件(通过url,uri,文件路径等等)。

Custom cache invalidation 自定义缓存校验:
改变唯一标识符是很困难的,而且Glide也提供了signature()签名api来增加额外的数据到cache key中。Media store的内容适合签名,最好是其它的内容能保持一些版本的元数据:

  1. Media store的内容:可以使用Glide的MediaStoreSignature类来作为签名。MediaStoreSignature可以用来混淆日期修改时间、mime type和MediaStore照片的旋转方向到cache key中。这三个属性可以准确的获取编辑和更新的mediaStore的缓存。
  2. 文件:可以使用StringSignature来混淆文件的修改时间。
  3. Url:尽管当url改变的时候为了确保服务端url的改变能让客户端也更新去验证url作为最好的方式,也还可以使用 StringSignature来签名混淆,通过特有的metadata来代替。

通过StringSignature来签名是很简单的:

Glide.with(yourFragment)
.load(yourFileDataMode)
.signature(new StringSignature(yourVersionMetadata))
.into(yourImageView);

Media store 的签名也是很简单的:

Glide.with(fragment)
.load(mediaStoreUri)
.signature(new MediaStoreSignature(mimeType, dateModified, orientation))
.into(view);

通过实现Key接口来自定义自己的签名,其中的 equals()、hashCode()、updateDiskCacheKey()方法必须实现:

public class IntegerVersionSignature implements Key{
    private int currentVersion;
    public IntegerVersionSignature(int currentVersion){
        this.currentVersion = currentVersion;
    }

    @Override
    public boolean equals(Object o){
        if(o instanceof IntegerVersionSignature){
            IntegerVersionSignature other = (IntegerVersionSignature) o;
            return currentVersion = other.currentVersion;
        }
        Return false;
    }

    @Override
    public int hashCode(){
        return currentVersion;
    }

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest){
        messageDigest.update(ByteBuffer.allocate(Integer.SIZE).putInt(signature).array());
    }
}

请记住,为了避免降低性能,在你想加载图片的时候,你需要在后台批量的加载任意版本的metadata。
也可以使用diskCacheStrategy()的DiskCacheStrategy.NONE来让磁盘缓存失效。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:44446次
    • 积分:832
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:2篇
    • 译文:6篇
    • 评论:48条
    最新评论