Glide4.10加载网络图片的基本流程

Glide4.10 加载网络图片的基本流程

Glide.with(context).load(url).into(imageView);
加载一张图片,主要经过上面三个步骤; 下面会逐个分析三个步骤;
本文针对的Glide 4.10版本;

第1步:with(context) 生成RequestManager对象

  1. 根据context是否是Application,Glide决定是否需要关注页面的生命周期;
  2. Glide通过添加一个空Fragment的方式感知生命周期变化;

第2步:load(url) 生成RequestManager对象

  • 大部分api在这个阶段添加到RequestManager, 比如listener();
  • 该阶段指定了model类型,本例中model是String类型的url;

第3步:into(imageView)

  1. 首先,使用imageView构造Target,into()主要任务:创建并且执行 Request: requestManager.track(target, request);
  2. 随后,执行Request的begin()方法, 本例为SingleRequest对象的begin()
  3. 执行Target的getSize()指定所需宽高;此时自定义Target可以设置想要的宽高;
  4. 最后,执行SingleRequest的onSizeReady(), 调用Engine对象的load()方法开始加载;

第3.1步骤: Engine.load() 加载图片

  • 首先试图从内存缓存(内存缓存分两级)中取,loadFromMemory() 步骤:
    • loadFromActiveResources():根据Key从ActivieResources集合获取;
      • ActivieResources为1级内存缓存,存储当前Activity正在使用的资源;
    • loadFromCache():再从MemoryCache中获取;
      • MemoryCache为2级内存缓存,该接口的实现类为LruResourceCache;
  • 如果loadFromMemory() 没获取到缓存Resource,则从文件缓存或者数据源获取;
  • Engine对象waitForExistingOrStartNewJob()创建EngineJob和DecodeJob;
    • EngineJob是从Pools.Pool> pool对象池获取;DecodeJob类似;
    • DecodeJob继承自Runnable;EngineJob会启动DecodeJob;
  • DecodeJob的run()方法,核心逻辑在DecodeJob的runWrapped()方法;
  • runWrapped()方法,主要通过状态机runReason控制;
  • 首先将状态机runReason初始为RunReason.INITIALIZE;
  • 执行getNextGenerator()获取DataFetcherGenerator;
    • DataFetcherGenerator接口用来获取数据,它有三个具体实现类:
      • ResourceCacheGenerator:获取downsampled/transformed的资源数据;
      • DataCacheGenerator:获取原始未修改过的资源数据;
      • SourceGenerator:意味着从原始数据源获取数据;
    • 依次查询上面3个实现类;本例为第一次获取图片情形,currentGenerator最终为SourceGenerator,即需要从Source中取数据;
  • 执行currentGenerator的startNext(),核心逻辑:寻找合适的LoadData,进而生成Fetcher,执行Fetcher的loadData()方法获取InputStream;
    • 从ModelLoader集合中寻找合适的ModelLoader,依据是boolean handles(Model), 该方法返回true表示可以处理该Model;
      • Glide对象初始化时注册所有ModelLoader,将其存储在Registry对象中;
        • ModelLoader列表可以通过GlideContext获取;
      • 本例为加载网络图片,Loader为HttpUriLoader,因为它的handles()方法是判断scheme是否为http或https;
    • HttpUriLoader的model是Uri类型,它将model包装为GlideUrl类型,将load工作交给HttpGlideUrlLoader的buildLoadData()
    • HttpGlideUrlLoader的buildLoadData()创建用于网络通信的HttpUrlFetcher对象;网络通信的结果是InputStream, 随后需要将其decode为Resource;
    • fetcher拿到IS后,回调DecodeJob的onDataFetcherReady(Key, Resource ...)
  • DecodeJob通过回调拿到fetcher,执行decodeFromRetrievedData()解码,拿到Resource对象;
    • 执行decodeFromData() 获取Resource, 具体逻辑在decodeFromFetcher():
      • decodeHelper.getLoadPath()获取LoadPath;
        • 首先通过getDecodePaths()获取DecodePath列表;
          • DecodePath和ModelLoader类似,都是注册在Registry,也是通过handles()方法判断;
        • 本例的DecodePath列表中只包含ByteBufferBitmapDecoder;
        • 使用DecodePath列表创建并返回一个LoadPath:
      • 执行LoadPath的runLoadPath()方法:返回Resource;
        • 遍历DecodePath列表,调用DecodePath.decodeResource()进行解码;
        • 解码完成后,回调DecodeJob的onResourceDecoded(), 执行Transform、缓存等操作;
        • 本例Resource为Bitmap, 实际上Bitmap/Drawable/Gif等都实现Resource接口;
    • 拿到Resource后,调用DecodeJob的notifyEncodeAndRelease();
    • 回调EngineJob的onResourceReady(Resource) ,进一步执行notifyCallbacksOfResult():
      • 回调Engine的onEngineJobComplete(),将Resource保存到内存缓存中;
      • 回调SingleRequest的onResourceReady()回调listener(new RequestListener)中逻辑;
  • SingleRequest回调Target的同名方法onResourceReady(),完成最终的显示;
    • 本例执行into(ImageView),则会执行ImageViewTarget的onResourceReady()
    • ImageViewTarget的onResourceReady()调用抽象方法setResource(Resource),如果执行过asBitmap(), 便执行BitmapImageViewTarget的setResource(),具体为view.setImageBitmap(resource);
  • 此时图片便加载出来了;

你可能感兴趣的:(android,Glide)