Glide之旅 —— Key
来源:互联网 发布:张利国java 编辑:程序博客网 时间:2024/06/07 22:13
前言
glide是谷歌推荐的Android图片加载框架,其优秀的缓存策略、Activity的生命周期的继承、GIF图片的支持等都是为人所称道的地方。下面是用glide加载一张图片的调用。
private void loadImage() { Glide.with(this) .load("http://pic2.orsoon.com/2017/0118/20170118011032176.jpg") .into(ivTest);}
那么,该框架是如何实际运作的呢,我会通过“Glide之旅”系列博客尽可能详细地将我的心得记录下来。“Glide之旅”系列文章汇总:
Glide之旅 —— Registry
Glide之旅 —— Key
Glide之旅 —— DecodeJob
概述
Key(com.bumptech.glide.load.Key),顾名思义,是用来作为图片的唯一标识,那么具体又是怎样的呢?
已知实现类
Key是一个接口,其所有实现类有
com.bumptech.glide.load.resource.bitmap.BitmapDrawableTransformation
com.bumptech.glide.load.engine.prefill.BitmapPreFillRunner.UniqueKey
com.bumptech.glide.load.resource.bitmap.BitmapTransformation
com.bumptech.glide.load.resource.bitmap.CenterCrop
com.bumptech.glide.load.resource.bitmap.CenterInside
com.bumptech.glide.load.resource.bitmap.CircleCrop
com.bumptech.glide.load.engine.DataCacheKey
com.bumptech.glide.signature.EmptySignature
com.bumptech.glide.load.engine.EngineKey
com.bumptech.glide.load.resource.bitmap.FitCenter
com.bumptech.glide.load.resource.gif.GifDrawableTransformation
com.bumptech.glide.load.resource.gif.GifFrameLoader.FrameSignature
com.bumptech.glide.load.model.GlideUrl
com.bumptech.glide.signature.MediaStoreSignature
com.bumptech.glide.load.MultiTransformation<T>
com.bumptech.glide.signature.ObjectKey
com.bumptech.glide.load.Options
com.bumptech.glide.load.engine.ResourceCacheKey
com.bumptech.glide.load.resource.bitmap.RoundedCorners
com.bumptech.glide.load.resource.UnitTransformation<T>
GlideUrl
当调用前言中的loadImage()
进行图片加载的时候,结合我的Glide之旅 —— DecodeJob一文中的源码流程可知,用SourceGenerator
解码远程图片的时候,首先会执行到com.bumptech.glide.load.model.stream.HttpUriLoader.Factory#build(MultiModelLoaderFactory)
,先来看下源码
package com.bumptech.glide.load.model.stream;...public class HttpUriLoader implements ModelLoader<Uri, InputStream> { ... public static class Factory implements ModelLoaderFactory<Uri, InputStream> { @Override public ModelLoader<Uri, InputStream> build(MultiModelLoaderFactory multiFactory) { return new HttpUriLoader(multiFactory.build(GlideUrl.class, InputStream.class)); } @Override public void teardown() { // Do nothing. } }}
那么显然,根据Glide之旅 —— Registry中介绍的获取注册项方法可知,需要在ModelLoaderRegistry
数据集合中找出Entry
第一个传参为GlideUrl.class
,第二个传参为InputStream.class
的数据项,可知符合条件的有
23. new MultiModelLoaderFactory.Entry(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
那么,此时再来看下com.bumptech.glide.load.model.stream.HttpGlideUrlLoader
的源码
package com.bumptech.glide.load.model.stream;...public class HttpGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> { public static final Option<Integer> TIMEOUT = Option.memory( "com.bumptech.glide.load.model.stream.HttpGlideUrlLoader.Timeout", 2500); @Nullable private final ModelCache<GlideUrl, GlideUrl> modelCache; public HttpGlideUrlLoader() { this(null); } public HttpGlideUrlLoader(ModelCache<GlideUrl, GlideUrl> modelCache) { this.modelCache = modelCache; } @Override public LoadData<InputStream> buildLoadData(GlideUrl model, int width, int height, Options options) { GlideUrl url = model; if (modelCache != null) { url = modelCache.get(model, 0, 0); if (url == null) { modelCache.put(model, 0, 0, model); url = model; } } int timeout = options.get(TIMEOUT); return new LoadData<>(url, new HttpUrlFetcher(url, timeout)); } @Override public boolean handles(GlideUrl model) { return true; } public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> { private final ModelCache<GlideUrl, GlideUrl> modelCache = new ModelCache<>(500); @Override public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) { return new HttpGlideUrlLoader(modelCache); } @Override public void teardown() { // Do nothing. } }}
可以看到,buildLoadData(GlideUrl, int, int, Options)
的返回值为new LoadData<>(url, new HttpUrlFetcher(url, timeout))
,其中,url
就是一个用访问的图片地址转换成的GlideUrl
对象
package com.bumptech.glide.load.model;...public interface ModelLoader<Model, Data> { class LoadData<Data> { public final Key sourceKey; public final List<Key> alternateKeys; public final DataFetcher<Data> fetcher; public LoadData(Key sourceKey, DataFetcher<Data> fetcher) { this(sourceKey, Collections.<Key>emptyList(), fetcher); } public LoadData(Key sourceKey, List<Key> alternateKeys, DataFetcher<Data> fetcher) { this.sourceKey = Preconditions.checkNotNull(sourceKey); this.alternateKeys = Preconditions.checkNotNull(alternateKeys); this.fetcher = Preconditions.checkNotNull(fetcher); } } ...}
也就是说,该LoadData
对象的sourceKey
为一个GlidUrl
对象,而该GlidUrl
对象是有图片来源地址转换而来的,看下GlideUrl
源码
package com.bumptech.glide.load.model;...public class GlideUrl implements Key { private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%"; private final Headers headers; @Nullable private final URL url; @Nullable private final String stringUrl; @Nullable private String safeStringUrl; @Nullable private URL safeUrl; @Nullable private volatile byte[] cacheKeyBytes; private int hashCode; public GlideUrl(URL url) { this(url, Headers.DEFAULT); } public GlideUrl(String url) { this(url, Headers.DEFAULT); } public GlideUrl(URL url, Headers headers) { this.url = Preconditions.checkNotNull(url); stringUrl = null; this.headers = Preconditions.checkNotNull(headers); } public GlideUrl(String url, Headers headers) { this.url = null; this.stringUrl = Preconditions.checkNotEmpty(url); this.headers = Preconditions.checkNotNull(headers); } public URL toURL() throws MalformedURLException { return getSafeUrl(); } private URL getSafeUrl() throws MalformedURLException { if (safeUrl == null) { safeUrl = new URL(getSafeStringUrl()); } return safeUrl; } public String toStringUrl() { return getSafeStringUrl(); } private String getSafeStringUrl() { if (TextUtils.isEmpty(safeStringUrl)) { String unsafeStringUrl = stringUrl; if (TextUtils.isEmpty(unsafeStringUrl)) { unsafeStringUrl = url.toString(); } safeStringUrl = Uri.encode(unsafeStringUrl, ALLOWED_URI_CHARS); } return safeStringUrl; } public Map<String, String> getHeaders() { return headers.getHeaders(); } public String getCacheKey() { return stringUrl != null ? stringUrl : url.toString(); } @Override public String toString() { return getCacheKey(); } @Override public void updateDiskCacheKey(MessageDigest messageDigest) { messageDigest.update(getCacheKeyBytes()); } private byte[] getCacheKeyBytes() { if (cacheKeyBytes == null) { cacheKeyBytes = getCacheKey().getBytes(CHARSET); } return cacheKeyBytes; } @Override public boolean equals(Object o) { if (o instanceof GlideUrl) { GlideUrl other = (GlideUrl) o; return getCacheKey().equals(other.getCacheKey()) && headers.equals(other.headers); } return false; } @Override public int hashCode() { if (hashCode == 0) { hashCode = getCacheKey().hashCode(); hashCode = 31 * hashCode + headers.hashCode(); } return hashCode; }}
- Glide之旅 —— Key
- Glide之旅 —— Registry
- Glide之旅 —— DecodeJob
- Glide 入门到精通之十五 ——用 Glide Module 自定义 Glide
- Glide源码之旅
- Glide 入门到精通之二——图片加载
- Glide 入门到精通之六——缓存基础
- Glide 入门到精通之七——请求优先级
- Glide 入门到精通之八——缩略图
- Glide 入门到精通之十二 ——自定义转换
- Glide 入门到精通之六——缓存基础
- Android框架之路——Glide的使用
- 第三方库之—Glide的使用
- Glide 入门到精通之一——添加Glide
- Glide 入门到精通之一——添加Glide
- Glide深入浅出(一)——Glide vs Picasso
- Glide入门教程——16.用Modules定制Glide
- Glide入门教程——18.Glide Module案例: 自定义缓存
- Linux服务器关闭SeLinux的方法
- 相关链接收藏
- LINUX下无法生成波形图的解决方案
- C++之priority_queue
- SELinux概述
- Glide之旅 —— Key
- 为PHP增加mongodb扩展模块
- smb记录
- np.where
- Ant配置
- samba 设置 网络共享
- Linux系统管理员成长经验:十一大工作心得
- C语言编译全过程【转】
- C语言——可变参数