首先这里推荐郭霖的博客https://blog.csdn.net/column/details/15318.html 他的文章可以起到很好的引导作用。不过读代码这件事还是要自己来一遍才会对代码理解的清楚。 阅读代码时要先走一遍流程,忽略细节,抓住流程中的几个重要点,然后把重要的点连成线。人的脑子是有限的,短时间容纳的东西也是有限的,只能捡重要的先装进去。 接下来就是分析这些重要的点,像迭代一样。

glide最基本的用法

Glide.with(context or fragment).load(url).into(imageview)

以下的类名是我自己的理解,是抽象总结出的东西,在源代码里会更复杂点

with会返回一个RequestManager,这个RequestManager会响应context或fragment的生命周期,做到这一点所使用的方法很有意思。

RequestManager.load会返回一个RequestBuilder,传入的参数会转化为GlideUrl。

RequestBuilder.into 在方法里创建一个Request,将imageView包装成一个Target,并作为返回值返回。

Request会在onSizeReady方法中放到Engine也就是线程池里。

onSizeReady的调用时机需要记录一下,顾名思义是在imageView大小可以确定的情况下调用的方法。into调用时,不过不能确定,就根据imageView的layoutparam计算一下,计算完后如果不是固定大小,就添加OnPreDrawListener,OnPreDrawListener被调用时,大小肯定是确定的。

在OnSizeReady里engine.load就算是开始正式运行

    public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
            DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
            Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb)

这个方法主要关注DataFetcher和DataLoadProiver,DataLoadProvider更重要点 DataFetcher作用于资源的获取,一般时我们使用的都是网络资源,郭霖的博客有一个用okhttp实现的DataFetcher, DataFetcher的实例是通过ModelLoader.getResourceFetcher获得的。

 /**
 * A load provider that provides the necessary encoders and decoders to decode a specific type of resource from a
 * specific type of data.
 *
 * @param <T> The type of data the resource will be decoded from.
 * @param <Z> The type of resource that will be decoded.
 */
public interface DataLoadProvider<T, Z> {

    /**
     * Returns the {@link com.bumptech.glide.load.ResourceDecoder} to use to decode the resource from the disk cache.
     */
    ResourceDecoder<File, Z> getCacheDecoder();

    /**
     * Returns the {@link com.bumptech.glide.load.ResourceDecoder} to use to decode the resource from the original data.
     */
    ResourceDecoder<T, Z> getSourceDecoder();

    /**
     * Returns the {@link com.bumptech.glide.load.Encoder} to use to write the original data to the disk cache.
     */
    Encoder<T> getSourceEncoder();

    /**
     * Returns the {@link com.bumptech.glide.load.ResourceEncoder} to use to write the decoded and transformed resource
     * to the disk cache.
     */
    ResourceEncoder<Z> getEncoder();
}

当资源成功获得后,就需要解码编码,是转化成图片还是转化成什么,缓存时就是编码了,从缓存中获取资源解码就是getCacheDecoder了。

成功获取,成功解码,转化为我们想要的可使用的资源(通常是图片),下面就是通知request了,GenericRequest实现了ResourceCallback,onResourceReady被调用,这里该加动画加动画,该干嘛干嘛了。

Glide是一个设计良好的Pipeline,上面空出Slot,等待我们填充,Glide准备了一套默认的,之后还可以根据我们自己的需求进行替换。这里说的就是自定义模块了可以看郭霖的第六篇文章[https://blog.csdn.net/guolin_blog/article/details/78179422]。

还有需要记录的一点就是Glide的缓存,Glide用的是强引用,并没有用弱引用的方法,避免内存抖动的问题,但随之带来的问题是对于不再需要的图片需要手动放到BitmapPool里。

Glide也很好的解决了这个问题 1.就是将图片的存活与生命周期绑定,就是在Glide.with里做的事情。 2.可以看ViewTarget里getRequest,将Request放到了view的tag里,下次再进行另外一个request的话,会取消上一个,也就进行了资源释放。

另外Engine EngineJob DecodeJob EngineRunnable 的业务对接也很有意思。