您当前的位置: 首页 >  网络

郭梧悠

暂无认证

  • 1浏览

    0关注

    402博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Glide 4.x之请求网络图片数据流程解析

郭梧悠 发布时间:2017-11-01 20:40:38 ,浏览量:1

在《Glide工作总体执行流程概述》一篇博文中简单分析了glide的工作流程,简而言之就是Glide先构建RequestManager对象,然后RequestManager对象构建ReqeustBuilder对象,再由RequsetBuilder对象创建一个Requset对像,最后将Request交给RequsetMangaer管理,然后RequestManager通知request调用begin发起请求将生成的图片资源交给具体的Target的过程。只不过上篇文章只是简单的做了梳理工作,并没有对详细的说明,本篇就承接上文来继续分析。所以建议读此篇博文的童鞋大致瞅一眼《Glide工作执行流程概述》

本篇还是以SingleRequest为例来说明,在资源还没有加载好的时候,SingleRequest的begin方法会调用一个onSizeReady方法:

public void begin() {
    //省略部分代码
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } 
   //省略部分代码

  }

进入onSizeReady内部翻看一翻,仍然剔除暂时与本文无关的代码:

private Engine engine;
public void onSizeReady(int width, int height) {
    //省略部分代码
    status = Status.RUNNING;

    loadStatus = engine.load(glideContext,model,//url
        //省略一大堆参数);

  }

也就是说onSizeReady方法内部也就是主要时调用来Engine对象的load方法,那么这个engine对象是什么鬼呢?先看看这个对象是时候初始化的,该对象是在初始化Glide对象的时候进行来初始化,具体的可在GlideBuilder的build方法找到:

 public Glide build(Context context) {

   //省略本分代码

    //如果客户端没有配置自己的Engine
    if (engine == null) {
      engine = new Engine(memoryCache, diskCacheFactory, diskCacheExecutor, sourceExecutor,
          GlideExecutor.newUnlimitedSourceExecutor());
    }

    return new Glide(context,engine,//省略一大堆参数);
  }

从Engine类的构造起所需要的参数来看,Engine负责内存缓存,磁盘缓存等等管理工作,这些内存和磁盘缓存等相关的类可以通过Builder模式让客户端自己构建自己的缓存逻辑,这也是Builder模式的强大之处,该模式也算是常用的设计模式之一,其设计理念还是很值得借鉴的,到此为止Engine的初始化已经创建完毕。下面继续沿着SingleRequest的流程分析engine.load方法:

//返回一个LoadStatus对象
 public  LoadStatus load(//一大堆参数) {
    //1、生成一个EngineKey对象
    EngineKey key = keyFactory.buildKey(model,//url
     signature, width, height, transformations,
        resourceClass,
         transcodeClass, //Drawable.class
         options);
   //2、从缓存加载图片资源
    EngineResource job = (EngineJob) message.obj;
      switch (message.what) {
        case MSG_COMPLETE:
          job.handleResultOnMainThread();
          break;

      }
      return true;
    }

仅仅是调用了EngineJob的handleResultOnMainThread方法,此时我们已经将图片数据切换到了UI线程:

  void handleResultOnMainThread() {
    //省略部分代码
    //将数据转换成engineResource
    engineResource = engineResourceFactory.build(resource, isCacheable);
    hasResource = true;

  //省略部分代码
    for (ResourceCallback cb : cbs) {
      if (!isInIgnoredCallbacks(cb)) {
       //特么的第四个callback
        cb.onResourceReady(engineResource, dataSource);
      }
    }

  }

该方法做了两件事: 1、将resource交给engineResource来持有 2、将engineResource交给本文的**第四个callback**

那么这第四个callback又是什么?是ResourceCallback接口,该接口是通过初始化EngineJob的时候调用EngineJob的 addCallback(ResourceCallback cb)方法传进来的。且EngineJob 的初始化是在Engine的load 方法中,而load 的方法的一个参数就是又这个callback, 且load的调用又是在文章开头的SingleReqeust方法,顺藤摸瓜发现第四个callback就是SingleReqeust,所以我们进入该SingleReqeust的onResourceReady方法:

 public void onResourceReady(Resource resource, DataSource dataSource) {
    //调用重载方法:
    onResourceReady((Resource) resource, (R) received, dataSource);
  }

private void onResourceReady(Resource resource, R result, DataSource dataSource) {

    this.resource = resource;
    //最终调用target的onResourceReady
     target.onResourceReady(result, animation);

  }

如果你读过博主的《Glide工作总体执行流程概述》这篇文章的话,就可以知道此处的target就是DrawableImageViewTarget,该target的onResourceReady方法的最总逻辑就是调用:

imageView.setImageDrawable(resource);

来完成图片的展示。

到此为止,本篇分析完毕,分析源码的过程中四个callback来回调度可把我绕坏了,为了本篇博文的主题连续性,基本上省略了好多东西没讲,什么ModelLoader啦,LoadData啦,Fetcher啦,将在后续博文中讲解,敬请期待,如有不当之处,欢迎批评指正

关注
打赏
1663674776
查看更多评论
立即登录/注册

微信扫码登录

0.0470s