Glide 源码解析(一) 加载流程

Glide介绍

Glide 是Google 员工 bumptech 开源的一款图片加载框架,相对于UniversalImageLoader,Picasso,它还支持video,Gif,SVG格式,支持缩略图请求,旨在打造更好的列表图片滑动体验。Glide有生命周期的概念(主要是对请求进行pause,resume,clear),而且其生命周期与Activity/Fragment的生命周期绑定,支持Volley,OkHttp,并提供了相应的integration libraries,内存方面也更加友好。

本文选择的Glide 版本是 4.2.0, 源码下载地址

代码结构图如下:

这里写图片描述

Glide 库是使用流接口(fluent interface)。对一个完整的功能请求,Glide 建造者要求最少有三个参数。
with(Context context) - 对于很多 Android API 调用,Context 是必须的。Glide 在这里也一样
load(String imageUrl) - 这里你可以指定哪个图片应该被加载,它可以是 URL ,资源 ID 或者是一个文件
into(ImageView targetImageView) 图片会显示到对应的 ImageView 中。

代码中的使用

Glide.with(this)
    .load("https://img-my.csdn.net/uploads/201407/26/1406382900_2418.jpg")
    .into(giphyLogoView);

总体设计流程图

这里写图片描述

Glide 中涉及到的概念

1、Target Glide 将显示目标封装为 Target, 将图片显示到ImageView 上。
2、Model 对数据源的描述,它可以是 URL ,资源 ID 或者是一个文件。G里的从哪里获取图片
3、Data 从数据源中获取 InputStream ,Glide 中称之为 Data。负责从数据源中获取原始数据的角色称为 ModelLoader
4、Resource 对原始数据InputStream 解码,解码为 Bitmap 或者 GifDrawable。解码后的资源称为 Resource。完成解码的角色称为 ResourceDecoder。
5、转码。Glide 除了能加载静图外,还能加载动图 Gif 。但是解码后静图类型 Bitmap 与 GifDrawable 并不统一。为了逻辑方便处理,Glide 会将 Bitmap 转码成 GlideBitmapDrawable。这样类型就能统一了,都是 GlideDrawable。负责转码的角色称为 Transcoder
6、变换。根据图片设置的 ScaleType,做 FitCenter、CenterCrop 等转换。 在 Glide 中用 ResourceTranscoder 表示。

请求流程

with方法

public static RequestManager with(Context context) {
  return getRetriever(context).get(context);
}

public static RequestManager with(Activity activity) {
  return getRetriever(activity).get(activity);
}

public static RequestManager with(FragmentActivity activity) {
  return getRetriever(activity).get(activity);
}

public static RequestManager with(android.app.Fragment fragment) {
  return getRetriever(fragment.getActivity()).get(fragment);
}

public static RequestManager with(Fragment fragment) {
  return getRetriever(fragment.getActivity()).get(fragment);
}

public static RequestManager with(View view) {
  return getRetriever(view.getContext()).get(view);
}

with() 为Glide 中的静态方法, 可以看到有6个重载方法,都创建了一个RequestManagerRetriever实例然后调用了get()方法。下面我们看 getRetriever()方法

private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  // Context could be null for other reasons (ie the user passes in null), but in practice it will
  // only occur due to errors with the Fragment lifecycle.
  Preconditions.checkNotNull(
      context,
      "You cannot start a load on a not yet attached View or a  Fragment where getActivity() "
          + "returns null (which usually occurs when getActivity() is called before the Fragment "
          + "is attached or after the Fragment is destroyed).");
  return Glide.get(context).getRequestManagerRetriever();
}

通过该方法返回了RequestManagerRetriever的单例实现,下面我们看看RequestManagerRetriever 中的get() 方法逻辑

// Visible for testing.
public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
  this.factory = factory != null ? factory : DEFAULT_FACTORY;
  handler = new Handler(Looper.getMainLooper(), this /* Callback */);
}
private RequestManager getApplicationManager(Context context) {
  // Either an application context or we're on a background thread.
  if (applicationManager == null) {
    synchronized (this) {
      if (applicationManager == null) {
        // Normally pause/resume is taken care of by the fragment we add to the fragment or
        // activity. However, in this case since the manager attached to the application will not
        // receive lifecycle events, we must force the manager to start resumed using
        // ApplicationLifecycle.

        // TODO(b/27524013): Factor out this Glide.get() call.
        Glide glide = Glide.get(context);
        applicationManager =
            factory.build(glide, new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
      }
    }
  }

  return applicationManager;
}
public RequestManager get(Context context) {
  if (context == null) {
    throw new IllegalArgumentException("You cannot start a load on a null Context");
  } else if (Util.isOnMainThread() && !(context instanceof Application)) {
    if (context instanceof FragmentActivity) {
      return get((FragmentActivity) context);
    } else if (context instanceof Activity) {
      return get((Activity) context);
    } else if (context instanceof ContextWrapper) {
      return get(((ContextWrapper) context).getBaseContext());
    }
  }

  return getApplicationManager(context);
}
public RequestManager get(FragmentActivity activity) {
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  } else {
    assertNotDestroyed(activity);
    FragmentManager fm = activity.getSupportFragmentManager();
    return supportFragmentGet(activity, fm, null /*parentHint*/);
  }
}
public RequestManager get(Fragment fragment) {
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值