美文网首页
Glide 图片加载库源码分析3-load 方法创建加载请求

Glide 图片加载库源码分析3-load 方法创建加载请求

作者: jkwen | 来源:发表于2021-07-11 07:19 被阅读0次

    先说前面分析的 Glide 的 with 方法,返回的是 RequestManager 对象,但实际上经过 GlideApp 的包装,被转型成了 GlideReuqests 对象。

    public static RequestManager with(@NonNull FragmentActivity activity) {
        return getRetriever(activity).get(activity);
    }
    public static GlideRequests with(@NonNull FragmentActivity activity) {
        return (GlideRequests) Glide.with(activity);
    }
    

    GlideRequests 继承自 RequestManager,是通过 APT 生成的类,这里面包括了我们通过注解扩展出的功能方法,但默认没有扩展的情况下,其实它就等价于 RequestManager。

    这样子的话就明确了 load 方法是 GlideRequests 提供的,

    public GlideRequest<Drawable> load(@Nullable String string) {
        return (GlideRequest<Drawable>) super.load(string);
    }
    

    通过调用父类的方法,将返回结果转型为 GlideRequest<Drawable>。

    public RequestBuilder<Drawable> load(@Nullable String string) {
        return asDrawable().load(string);
    }
    public RequestBuilder<Drawable> asDrawable() {
        return as(Drawable.class);
    }
    public <ResourceType> RequestBuilder<ResourceType> as(Class<ResourceType> resourceClass) {
        return new RequestBuilder<>(glide, this, resourceClass, context);
    }
    

    调用 asDrawable 方法来获取一个 RequestBuilder 对象,RequestBuilder 是个泛型类,支持多种资源类型,例如 File, Bitmap, Gif,在这里是通过 as-xxx 方法表现的,但最终都会通过 as 这个泛型方法来实现。

    这个泛型方法的泛型命名为 ResourceType,其实和我们平时用的 T,K,V 这种一样,只不过这种更明显知道用意(这点是我们写泛型方法,泛型类的时候可以借鉴的)。

    protected RequestBuilder(Glide glide, RequestManager requestManager, Class<TranscodeType> transcodeClass, Context context) {
        this.glide = glide;
        this.requestManager = requestManager;
        this.transcodeClass = transcodeClass;
        this.context = context;
        this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
        this.glideContext = glide.getGlideContext();
    
        initRequestListeners(requestManager.getDefaultRequestListeners());
        apply(requestManager.getDefaultRequestOptions());
    }
    

    逐行看下,

    glide 就是 Glide 对象,requestManager 就是 RequestManager 对象。

    transcodeClass 这里就以 Drawable.class 类对象为例,对应的 TranscodeType 就是这个泛型类定义的泛型。

    context 就是 Activity 对象。这里要区分一下 Glide 对象里也有 context 属性,它是通过 getApplicationContext 方法获取的,RequestManager 对象里的 context 属性是 Activity 类型,所以这里的 context 就是 Activity 类型。

    transitionOptions 是通过 RequestManager 对象获取到的一个默认形变选项?经过简单的层层分析,这个来源是通过 GlideBuilder 进行配置的,在默认情况下这会是初始化对象。

    glideContext 定义为 Glide 的全局上下文,继承自 ContextWrapper,看这内容还挺多,这里知道它比较重要就行。

    initRequestListeners 方法要做的事情同 transitionOptions,默认情况下也是一个初始化对象。

    最后一行代码的调用是为了配置 RequestOptions,这个值依然是通过 RequestManager,在 GlideContext 里是通过工厂方法创建返回给 RequestManager 对象的,而这个工厂对象的实现是在 Glide 对象的创建过程中赋值的,因为是 Builder 模式,在没有配置的情况下,可以看下 GlideBuilder 里有没有默认初始值,果然在 GlideBuilder 里有默认的实现,

    private RequestOptionsFactory defaultRequestOptionsFactory =
        new RequestOptionsFactory() {
          @NonNull
          @Override
          public RequestOptions build() {
            return new RequestOptions();
          }
    };
    

    这样一来,RequestBuilder<Drawable> 对象就有了,同 GlideApp, Glide 的关系一样,RequestBuilder 和 GlideRequest 也是这么一对。

    所以 load 方法就最终返回了 GlideRequest<Drawable> 对象。

    对比 Picasso,Glide 的这两个方法调用逻辑和 Picasso 大体上有些类似。

    //获取到了 Picasso 对象
    Picasso.get();
    //Picasso 对象调用获取到 RequestCreator
    Picasso.load(url);
    
    //创建 Glide 对象,并获取到了 RequestManager(GlideRequests) 对象
    GlideApp.with();
    //GlideRequests(RequestManager) 对象调用获取到 GlideRequest
    GlideRequests.load();
    

    图片请求加载过程可以认为有这么几步,1. 创建外观类(Picasso, Glide 类)对象,2. 创建请求管理者,3. 创建请求并发起请求,4. 处理结果。对比 Picasso 和 Glide,虽然类似,但还是有区别,总体来看,Picasso 的前两步更像是 Glide 的第一步,即 创建请求管理者,Picasso 的第三步会创建请求并发起,而 Glide 则将创建请求和发起请求做了拆分,创建请求 对应着 Glide 的第二步。

    相关文章

      网友评论

          本文标题:Glide 图片加载库源码分析3-load 方法创建加载请求

          本文链接:https://www.haomeiwen.com/subject/sntxpltx.html