我是靠谱客的博主 魁梧哈密瓜,最近开发中收集的这篇文章主要介绍Glide框架解析---磁盘缓存与加载器(二)一、磁盘缓存二、加载器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、磁盘缓存

其实磁盘缓存的原理没什么好说的?为什么这么说呢?因为Glide磁盘缓存的实现使用的也是JakeWharton大神的DisLruCache,所以呢,我们也是直接拿过来用即可,直接把这三个文件直接Copy即可。下面我们来说一下磁盘缓存怎么去使用:

首先我们先写一个磁盘缓存用到的接口类DiskCache

public interface DiskCache {
    interface Writer {
        boolean write(File file);
    }
    File get(Key key);

    void put(Key key, Writer writer);

    void delete(Key key);

    void clear();
}

get,put,delete,clear这四个方法看名字就知道具体的作用,至于Writer和它的write方法,主要就是对图片进行解码,用到的时候我们具体说。下面是DiskCache的实现类DiskLruCacheWrapper:

public class DiskLruCacheWrapper implements DiskCache {
    final static int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
    final static String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
    private MessageDigest MD;
    private DiskLruCache diskLruCache;
    public DiskLruCacheWrapper(Context context) {
        this(new File(context.getCacheDir(), DEFAULT_DISK_CACHE_DIR), DEFAULT_DISK_CACHE_SIZE);
    }
    protected DiskLruCacheWrapper(File directory, long maxSize) {
        try {
            MD = MessageDigest.getInstance("SHA-256");
            //打开一个缓存目录,如果没有则首先创建它,
            // directory:指定数据缓存地址
            // appVersion:APP版本号,当版本号改变时,缓存数据会被清除
            // valueCount:同一个key可以对应多少文件
            // maxSize:最大可以缓存的数据量
            diskLruCache = DiskLruCache.open(directory, 1, 1, maxSize);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public String getKey(Key key) {
        key.updateDiskCacheKey(MD);
        return new String(Utils.sha256BytesToHex(MD.digest()));
    }
    @Nullable
    @Override
    public File get(Key key) {
        String k = getKey(key);
        File result = null;
        try {
            DiskLruCache.Value value = diskLruCache.get(k);
            if (value != null) {
                result = value.getFile(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 加入磁盘缓存
     * @param key
     * @param writer
     */
    @Override
    public void put(Key key, Writer writer) {
        String k = getKey(key);
        try {
            DiskLruCache.Value current = diskLruCache.get(k);
            if (current != null) {
                return;
            }
            DiskLruCache.Editor editor = diskLruCache.edit(k);
            try {
                File file = editor.getFile(0);
                if (writer.write(file)) {
                    editor.commit();
                }
            } finally {
                editor.abortUnlessCommitted();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void delete(Key key) {
        String k = getKey(key);
        try {
            diskLruCache.remove(k);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void clear() {
        try {
            diskLruCache.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

简单的说一下:

构造方法中主要做了一些初始化的工作,包括:计算Hash的算法名称(我这里用的是SHA-256),初始化磁盘缓存的位置,版本,大小等。其他的四个方法就是一些具体的操作,可以自己看看,都不难,如果有问题可以给我留言。

二、加载器

我们先看一张架构图,然后我们再去理解这个加载器的流程

上面的架构图并不是真正Glide的架构模式,这个是我们要写的阉割版Glide的架构,不过流程基本没变。

这里的处理数据的模型只有4个,但是真正的Glide的数据处理模型有好几十个,我这里只拿出来几个比较常用的来说。

我们一步一步来:

第一步:Glide在初始化的时候,都会把相应的数据处理模型注册到ModelLoaderRegister中,模型中的Model指的是图片资源的类型,Data指的是加载文件后的输出类型,我这里一律以InputStream的格式进行输出。Factory主要就是创建相应ModelLoader来进行数据的加载(真正进行数据加载的其实是LoadData的fetcher,这个我们稍后说)。然后将这三个元素封装在一个Entry类中,加入到ModelLoaderRegister中。

第二步:当图片资源加入到Glide时,系统会根据资源的类型,在ModelLoaderRegister中查找,哪种数据模型可以处理这个图片资源。当然查找的结果可能是多种,也可能是一种,所以我们使用List来装。找到符合的数据模型后,Factory就会调用build来创建一个ModelLoader对象。比如图片资源File类型时,找到的Factory是FileLoader.Factory,但它在build的时候,其实是ModelLoaderRegister根据Model为Uri,Data为InputStream进行build相应的ModelLoader(估计到这里,好多同学就懵了。怎么又回去了?FileLoader感觉什么也没做呢?是的,其实FileLoader更像是中转站)。ModelLoaderRegister在build的时候,又会出现上面的问题,ModelLoader可能有一个,也有可能是多个,怎么办?我们还要保证返回值是同一类型。有的同学可能会说,可以使用List。我认为这样设计没有问题。ModelLoader中都有一个buildData,方法的参数就是图片资源,我们可以在这里对List进行遍历,拿出每个ModelLoader来进行handle,看看能不能处理图片资源。但是这就要每个ModelLoader都要在这个方法中写循环的重复代码,很冗余。所以Glide就创建了一个叫做MultiModelLoader的类,它也是ModelLoader,在这个类里面有一个ModelLoader的集合。所以ModelLoaderRegister在build的时候,如果是一个则返回相应的ModelLoader;如果是多个,则统一放在MultiModelLoader的集合里,判断逻辑统一在MultiModelLoader的buildData方法来做。

第三步:如果图片是网络图片,那么ModelLoader最后会被定位为HttpUriLoader,通过buildData,找对应的HttpUriFetcher进行图片的获取;如果图片是本地图片,那么ModelLoader最后会被定位为FileUriLoader,通过buildData,找到对应的Fetcher为FileUriFetcher,然后进行资源的获取。

加载器这部分很重要,但是的确很难理解,我们需要反复的去看源码才可以,不是我几句话就能说得清楚的,我这里仅仅是抛砖引玉吧。代码我就不贴了,类实在是不少,我会把这部分的代码提供出来供大家研究。代码

欢迎大家提问和纠错!

 

 

最后

以上就是魁梧哈密瓜为你收集整理的Glide框架解析---磁盘缓存与加载器(二)一、磁盘缓存二、加载器的全部内容,希望文章能够帮你解决Glide框架解析---磁盘缓存与加载器(二)一、磁盘缓存二、加载器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(32)

评论列表共有 0 条评论

立即
投稿
返回
顶部