阅读 Glide 源码后的一些浅薄认识

Glide 里一句简单的 Glide.with(this).load(url).into(imageview) 背后其实有着非常复杂的逻辑和工作,这次正好碰巧有郭霖的博客在前方带路,我也顺便来看看 Glide 的源码实现。

在这篇文章里我不打算贴上大段的代码,我不会去仔细分析某段代码的作用,因为我自己或许都不太清楚,这篇文章我打算讲讲 Glide 实现的大体思路,通过这篇文章,你可以很快地知道 Glide 的大体架构,而不会深陷于代码的泥潭(主要还是源码实在太多太复杂了-_-||)。

首先说说 with() 方法,这个方法可以传入任何类型的 Context,Activity,Fragment,虽说是传进去了上下文的引用,但 Glide 并不持有这个引用,所以并不会造成内存泄露。这是为什么呢?我们知道,无论是 Activity 还是 Fragment,里面是可以继续持有 Fragment 的,而 Glide 很聪明,它向传进来的 Activity、Fragment 里面再添加一个 Fragment,因为 Fragment 与持有它的类的生命周期是绑定的,当外部 Activity、Fragment 的生命周期发生变化的时候,Glide 通过它添加的 Fragment 就可以感知到,从而及时停止或取消图片的加载,所以不会造成内存泄露。而如果你传入的是一个 Application 类型的 Context,那么这个图片加载的生命周期就会和 Application 保持一致,所以如果不是一个一直存在的图片,那么最好不要传入 Application 类型的 Context,因为过于长的生命周期会增加 App 同一时间内的负荷,占用更多的资源。总的来说 with() 方法就是用来预设这个图片加载的生命周期的。

然后就是 load() 方法:这个方法支持传入很多类型的资源,无论是 url、uri,还是 File,资源 ID,甚至是 byte 数组。在调用这个方法之后可以继续调用 asBitmap() 或者 asGif() 来设置图片的类型,这两个类型一动一静,始终贯穿在整个 load 过程中,如果不调用这两个方法,那么 load 方法就会自动识别,而一旦设定了具体的图片的类型,那么如果最后得到的图片与你的预设不相同,就会抛出异常。除了设置图片的类型,还可以设置图片的占位符(placeHolder)、错误提示图片(error),在 load 加载的过程中,会先后检查这两个变量的内容,在开始加载之前提供给 into 方法的是 placeHolder 图像,在加载出错的时候提供给 into 的是 error 图像。如果你还设置了变形、缩放、动画等,在 load 过程中其实并不会有什么特殊的处理,因为这些参数和设置只会在 into 过程中被真正的使用,load 过程就像烹饪之前的准备过程,知道我们要做什么菜,为了做这个菜需要哪些食材、需要什么调料、要做成什么口味等,都算是一个准备过程,并不会有具体的加工过程。load 过程中设置的所有参数最后一股脑地抛给 into 过程,由 into 过程来进行具体的解析、加载、加工、裁剪、转换等工作。

既然这样,那么最重要的东西都会在 into 过程中了。按照我的理解,我把这个过程分成以下几个步骤:

  • 构建:我们在 load 过程里设置了那么多的参数,图片类型,图片缩放、动画、翻转、占位符、错误提示等,都会在这里被调用,用这些参数构建出一个完整的 Glide 请求,是的,构建的结果是一个请求,什么请求呢,就是将某个图片加载出来的请求。
  • 解析:请求其实就是一个具体的目标,有了目标,就能够大步向前了。而解析的过程就是执行这个请求,在执行的一开始,就会在 imageview 上显示占位符,而如果执行出错就会显示预设的错误提示图片。在具体的执行过程中,根据不同的资源类型,会执行不同的图片加载过程,比如一开始传进去的是一个 url ,这里就会进行网络请求,获取结果流(inputStream),然后对这个流进行一系列的解码和封装。在这里还会判断图片是静态图还是动态图,分别有不同的解码过程。通过对流的解码会得到具体的 bitmap 对象,这个时候,请求里的其他参数就派上用场了,是否需要缩放,是否要旋转,是否设置动画,都会在这里得到具体的实现。
  • 包装:到这个时候,一个成熟的 bitmap /Gif 就做出来了,虽然这个图片可能就是我们需要的图片,但是还不能直接就显示出来。因为加载出来图片可能是动态地,也可能是静态的,这两种图片的设置的方法可不太一样。所以就需要我前面说到的封装了,而且是一系列的封装,以适应通用的设置图片的过程。
  • 转码:现在到我们手里的就是一个被包装了好几层的图片,而包装类并不直接或间接的继承于可以直接显示的 Drawable 和 Bitmap,那么还怎么显示呢?那就需要转码了。转码的作用的是从包装类中取出里面的 Drawable 或者 Bitmap 对象。那么我们不禁要问了,这又是包装的,又是转码的,最后不还是要用 Drawable 和 Bitmap 对象么?那么包装和转码到底有什么意义呢?问得好,因为 Glide 把你要显示图片的 imageView 也进行了一些封装,用来适应多种不同格式的图片,而为了适应封装过后的 ImageView,就得对图片进行转码。
  • 显示:这个时候就真的可以调用 setImageDrawable 或者 SetImageBitmap 将图片显示出来了,如果图片是 gif,就会不间断的播放 gif 的每一帧。

以上就是一个基本的 Glide 加载图片的完整流程。在这个流程里,完全没有提到图片缓存,就只是一个新图片第一次加载的过程。在郭霖博客的帮助下,我也花了差不多一天的时间来走完这一个流程,不得不说 Glide 的源码真的非常庞杂,随着方法的一层层深入,各种接口的实现,一不小心就会迷失在代码的海洋里,而忘记了一开始追溯到了哪一步。就像 Glide 文档说的,它背后默默完成了成吨的工作量。而阅读源码,不能过于深入,最好不要纠结于具体某一行代码的作用或逻辑,就像郭霖说的,抽丝剥茧,点到为止。先认准一个功能点,围绕这个功能点的流程具体是如何执行和实现的来展开调查,一点一点地进行渗透,最后慢慢的整个框架的思路和架构就会出现在你的脑海里。

希望我这篇很短的小文章对你理解 Glide 有一点点的帮助,如果文中描述有什么不对的,热切期望你能提出来,共同进步。要查看郭霖的更详细的解析,请移步 郭霖的博客

本文最早发布于alphagao.com

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

推荐阅读更多精彩内容