Android知识Android开发Android技术知识

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

2017-04-20  本文已影响142人  AlphaGao

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 过程中了。按照我的理解,我把这个过程分成以下几个步骤:

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

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

本文最早发布于alphagao.com

上一篇下一篇

猜你喜欢

热点阅读