Glide Decode


在DecodeJob的onDataFetcherReady()方法,将成功Fetcher抓取的数据保存,准备解析。

this.currentData = data;
this.currentFetcher = fetcher;
this.currentDataSource = dataSource;

将Object类型的数据转换成Resource<R>类型。

Data 处理流程

经过三个步骤,ResourceDecoder,Transformation 和 ResourceTranscoder 处理。

资源包装接口
Resource<T>,Resource.get()方法,返回T类型对象,如 Bitmap。

index Resource<T>
1 Resource<Bitmap> BitmapResource
2 Resource<File> FileResource
3 Resource<Drawable> DrawableResource
4 Resource<BitmapDrawable> LazyBitmapDrawableResource
5 Resource<GifDrawable> GifDrawableResource继承DrawableResource
6 Resource<byte[]> BytesResource

DataRewinder,原数据包装接口。

index DataRewinder 工厂 包装的类型
1 InputStreamRewinder InputStreamRewinder.Factory InputStream
2 ByteBufferRewinder ByteBufferRewinder.Factory ByteBuffer
3 DefaultRewinder 默认工厂.Factory Object

DataRewinderRegistry 注册。

根据Data的Class类型,选择DataRewinder.Factory<T>工厂,注册类包含工厂集合。InputStream和ByteBuffer类型有特定的DataRewinder工厂,其他选择默认DataRewinder工厂,
DataRewinder接口是对不同类型数据的统一封装,使用时rewindAndGet()方法,获得DataRewinder<T>的T数据,包括InputStream和ByteBuffer,以及Uri和File,它们来自DefaultRewinder。

一、Decode 流程

程序流程
private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
      throws GlideException {
    LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
    return runLoadPath(data, dataSource, path);
}

根据Data(Object)的Class类型,查找LoadPath,getLoadPath()方法,根据dataClass、resourceClass和transcodeClass,创建LoadPath,执行runLoadPath()方法。

private <Data, ResourceType> Resource<R> runLoadPath(Data data, DataSource dataSource,
      LoadPath<Data, ResourceType, R> path) throws GlideException {
    Options options = getOptionsWithHardwareConfig(dataSource);
    DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
    try {
      return path.load(
          rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
    } finally {
      rewinder.cleanup();
    }
}

Data包装DataRewinder<Data>,LoadPath的load()方法,遍历内部DecodePath列表,decode()方法。

public Resource<Transcode> decode(DataRewinder<DataType> rewinder, int width, int height,
      Options options, DecodeCallback<ResourceType> callback) throws GlideException {
    Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
    Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
    return transcoder.transcode(transformed, options);
}

遍历DecodePath内ResourceDecoder列表,查找匹配ResourceDecoder,将数据转换Resource<Z>类型。
在onResourceDecoded()进行Transformation变换处理。
最后ResourceTranscoder处理。

二、DecodePath 构建

getDecodePaths() 方法,返回 DecodePath<Data, TResource, Transcode> 列表。

注册类,ResourceDecoderRegistry,TranscoderRegistry。

根据 数据源和目标类 ,和子类 isAssignableFrom() 。ResourceDecoderRegistry 目标列表查询。在 RequestOptions 类 默认的目标类型 resourceClass 是 Object 类。
所有支持的 resourceClass 类型列表。

针对每一项支持的 resourceClass,和 需求 transcodeClass。
TranscoderRegistry类,查询可支持的 registeredTranscodeClass 转换列表。

这样,只要从 dataClass 到 resourceClass ,再到 transcodeClass,都可匹配,就是一条完整解析通道。

dataClass,每一项 resourceClass,对应 ResourceDecoder。
每一项 resourceClass,每一项 transcodeClass,对应 ResourceTranscoder。

DecodePath 全路径包括
dataClass,resourceClass,registeredTranscodeClass,ResourceDecoder 列表,ResourceTranscoder。

因此,构建 DecodePath 对象。

三、ResourceDecoder 解码

资源解码器 ResourceDecoder<T, Z> 接口。数据源 T,目标 Z,12个子类。
Z是 Resource<Z> 封装类型。

index T 数据源 Z 目标类型 ResourceDecoder 说明
1 DataType Bitmap BitmapDrawableDecoder 内部装饰者
2 ByteBuffer Bitmap ByteBufferBitmapDecoder Downsampler处理
3 InputStream Bitmap StreamBitmapDecoder Downsampler处理
4 ParcelFileDescriptor Bitmap VideoDecoder
5 AssetFileDescriptor Bitmap VideoDecoder
6 Uri Drawable ResourceDrawableDecoder Uri转换resId
7 Uri Bitmap ResourceBitmapDecoder 装饰者
8 File File FileDecoder 直接包装生成FileResource
9 Drawable Drawable UnitDrawableDecoder NonOwnedDrawableResource
10 Bitmap Bitmap UnitBitmapDecoder NonOwnedBitmapResource
11 ByteBuffer GifDrawable ByteBufferGifDecoder GifDrawableResource
12 InputStream GifDrawable StreamGifDecoder GifDrawableResource
13 GifDecoder Bitmap GifFrameResourceDecoder

将T类型数据,转换成Resource<Z>资源类型。
handle()方法,匹配data是ResourceDecoder支持的类型,decode()方法,解析,从包装DataRewinder类获取源数据,提供给ResourceDecoder。

解析成功,各类型源数据,封装Resource<T>图片资源数据BitmapDrawable,Bitmap,Drawable,GifDrawable,以及File。

DecodePath.DecodeCallback接口回调,onResourceDecoded()方法,通知资源解析成功,交给DecodeJob的onResourceDecoded()方法Transformation类处理。
DeferredEncodeManager初始化encode内容。

四、Transformation 变换

Transformation 类 transform() 方法,图片资源变换,生成一个 Resource<T> 新资源 。

index Transformation 处理类型
1 BitmapTransformation (抽象) Bitmap
2 DrawableTransformation Drawable
3 BitmapDrawableTransformation BitmapDrawable
4 GifDrawableTransformation GifDrawable
5 MultiTransformation 内部 Transformation 集合
6 UnitTransformation 不处理

子类重写 transform() 方法,不改变 Resource<ResourceType> 的 ResourceType 类型。

BitmapTransformation (抽象类) 子类,都是对 Bitmap 的变换。
CenterCrop,CenterInside,CircleCrop,FitCenter,RoundedCorners。

五、ResourceTranscoder 转换

资源类型转换。

index Z 源 R 目标 Transcoder
1 Bitmap BitmapDrawable BitmapDrawableTranscoder
2 Bitmap byte[] BitmapBytesTranscoder
3 Drawable byte[] DrawableBytesTranscoder
4 GifDrawable byte[] GifDrawableBytesTranscoder
5 Z Z UnitTranscoder 不改变

Resource<T> 类型转换。

目标类型,即 GlideRequest 构造方法 transcodeClass,即 as() 方法参数。
as() 方法支持类型包括 Bitmap,Drawable,GifDrawable,File,

如果用途是为了显示在 ImageView,仅支持目标类型 Bitmap 和 Drawable ,GifDrawable,转换目的是适配上层要求( as() 方法)的图片类型。

六、Encoder 持久化缓存

Resource 资源通知

上层转换成功,将 Resource<> 结果交给 notifyEncodeAndRelease() 方法。
1,notifyEncodeAndRelease()方法,通知。

任务状态Stage.ENCODE
notifyComplete()通知结束,DecodeJob.Callback回调onResourceReady(),即回到EngineJob。
通过EngineJob的onResourceReady()回调方法,资源数据Resource<?>存储。发送消息进入主线程,handleResultOnMainThread()处理。

cbs集合回调,SingleRequest实现了ResourceCallback接口,触发Target的onResourceReady()方法。

2,持久化 DeferredEncodeManager 处理,encode() 方法。
Encoder接口
定义encode()方法,将Data类型数据解析到File。

ResourceEncoder,Encoder<Resource<T>>,类型:Resource<T>
包含三个子类。

index Encoder 解析类型 策略 说明
1 ByteBufferEncoder ByteBuffer EncoderRegistry 注册
2 StreamEncoder InputStream EncoderRegistry 注册
3 BitmapEncoder Resource<Bitmap> TRANSFORMED
4 BitmapDrawableEncoder Resource<BitmapDrawable> TRANSFORMED 装饰者
5 GifDrawableEncoder Resource<GifDrawable> SOURCE Gif

前两者 父类, Encoder。
后三者父类,ResourceEncoder

boolean encode(@NonNull T data, @NonNull File file, @NonNull Options options);
encode方法,入参:<T>类型,如InputStream,ByteBuffer,Resource<Bitmap>,Resource<GifDrawable>
将data,缓存到file文件

编码策略:EncodeStrategy
1,TRANSFORMED
2,SOURCE
3,NONE


任重而道远

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271