懵了,面试官突然问我:Glide是干啥的?我对着那Glide新版本就是一顿暴讲

一直想写一个篇 Glide原理讲解,可一直没能动笔。

不是因为没时间,是 Glide 涉及太过广泛,内部逻辑太过犀利。一直没能找到一个合适的制高点来俯览全身。

之前对 Glide 一直停留在使用层面,只晓得使用方便,链式调用,节约内存,无所顾及内部原理,更没能学习其架构设计。

接下来我将通过以下几个问题来引伸分析Glide的内部逻辑,尽量做到 由使用到原理,从架构到逻辑,深入浅出。

  1. Glide是干啥的?
  2. 为什么用Glide?
  3. Glide怎么用?
  4. Glide包含哪些模块?都干什么用的?
  5. Glide调用某一个方法后具体干了什么事?

本文基于Glide的最新版本 4.10.0 进行分析,如有错误欢迎指出。

注:最新版本是4.11.0,发晚了,但是4.10.0 也算是非常非常新的了。

960页全网最全Android开发笔记:Android 基础、Java 基础、Android 源码相关分析、常见的一些原理性问题等等,帮助大家深刻理解Android相关知识点的原理以及面试相关知识。

1. 请用一脸懵逼的姿势了解,Glide到底是干啥的?

Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.

翻译成能听懂的

Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。

2. 那你为什么要用Glide?

有个不知道哪的人,不知道叫什么名的人曾经说过,当你开始问 为什么 的时候,那么你可能要变身了。

这个问题非常简洁,但分析透彻实属不易,甚至该问题是伴随使用的需求,场景变化而变化的。既然不好直观的分析说明,我们就罗列对应优势,方便需要的时候对号入座

  1. 优雅的调用姿 Glide.with(fragment).load(url).into(imageView);
  2. 多维度的图片格式(png,jpg,gif,webp,video等...)
  3. 健壮的身体素质 性能极好,能防止频繁主线程I/O,垃圾回收而导致的页面闪烁卡顿等。
  4. 灵活的加载请求 可根据页面的生命周期动态管理图片的加载请求。
  5. 风骚的缓存策略 支持按控件大小缓存对应大小的图片,且默认的图片格式为RGB_565,相对占用空间更小。速度也因此更快。

嗯~~~ 就看这几个,你说你要不要选Glide.....

3. Glide怎么用?

可算是到我闭着眼都能写的环节了,来来来,咱们撸代码。

首先增加如下引用。

implementation 'com.github.bumptech.glide:glide:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'

使用方式,我们罗列5种常用的使用方式:

//********************************** 直接使用 **********************************
Glide.with(Context).load("").into(mImageView)

//使用Generated API, 作用范围Application 模块内使用
//创建MyAppGlideModule类加上@GlideModule注解,buid后既能使用 GlideApp
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

//Generated API加载图片
GlideApp.with(Context).load("").into(mImageView);



//**********************************  添加占位图 **********************************
RequestOptions requestOptions = new RequestOptions()
         .placeholder(R.drawable.a)
         .error(R.drawable.e)
         .diskCacheStrategy(DiskCacheStrategy.NONE);//设置缓存了参数
Glide.with(Context).load("").apply(requestOptions).into(mImageView);

//Generated API 方式(和Glide3 一样)
GlideApp.with(Context).load("")
         .placeholder(R.drawable.a)
         .error(R.drawable.e)
         .diskCacheStrategy(DiskCacheStrategy.NONE)
         .into(mImageView);

// 后备回调符(Fallback) Generated API 方式才有
//在设置图片的场景中,如果用户不设置,也就是为null的情况,可使用后备回调符显示默认图
private static final String NULL_URL=null;
GlideApp.with(Context).load(NULL_URL)
         .fallback(R.drawable.a)
         .into(mImageView);


//**********************************  指定加载图片的大小(override) **********************************
RequestOptions requestOptions = new RequestOptions().override(200,100);
Glide.with(Context).load("").apply(requestOptions).into(mImageView);

//Generated API 方式
GlideApp.with(Context).load("")
             .override(200,100)
             .into(mImageView);


//**********************************  通过thumbnail加载缩略图 **********************************
//与placeholder类似,但是thumbnail可加载网络图,placeholder只能加载本地图。
RequestOptions requestOptions = new RequestOptions()
                .override(200,100)
                .diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(MainActivity.this)
                .load(url)
                .thumbnail( Glide.with(this)
                .load(url)
                .apply(requestOptions))
                .into(iv);

//Generated API 方式
 GlideApp.with(Context)
            .load(url)
            .thumbnail( GlideApp.with(this)
            .load(IMAGE_URL).override(200,100)          
            .diskCacheStrategy(DiskCacheStrategy.NONE))
            .into(mImageView);


//**********************************  设置图片的变化操作 **********************************
//可通过
//CenterCrop(图片原图的中心区域进行裁剪显示)
//FitCenter(图片原始长宽铺满)
//CircleCrop(圆形裁剪)
//设置图片的变化操作
Glide.with(Context)
            .load(IMAGE_URL)
            .apply(RequestOptions.circleCropTransform())
            .into(mImageView);

//Generated API 方式
GlideApp.with(Context).load(IMAGE_URL)
            .circleCrop()
            .diskCacheStrategy(DiskCacheStrategy.NONE)
            .into(mImageView);

4. Glide包含哪些模块?都干什么用的?

接下来的环节将是本篇文章的高地。

我们可以先简单思考下,如果你是Glide的作者,你要怎么设计一个优秀的图片加载框架,需要兼顾哪些环节,需要包含哪些模块?

简单来说,图片加载需要以下几种模块。

  1. 参数封装
  2. 加载请求
  3. 执行引擎
  4. 数据加载器
  5. 解码器
  6. 编码器
  7. 缓存

那实际Glide是这样设计的么?

  • 参数封装(获得请求的参数,配置加载图的属性)
  • 网络请求(下载图片)
  • 缓存逻辑(资源重用)
  • 加解码(处理图片)
  • 数据加载(判断加载方式/请求网络/IO读取/内存读取)
  • 线程池/线程队列(或者叫任务队列,用于处理每次的加载任务)
  • 防止OOM的处理机制(软引用,缓存,压缩,存储等..)
  • 生命周期管理(防止内存泄露)
  • .......

说了这么多,那加载一张图片,到底是怎样一个流程呢?换句话说,这些模块具体是怎样协同工作的,调用顺序又是怎样的呢?

给大家画了一个简单的图,兄弟们,这个图来之不易啊,你不从头捋一遍你真是不知道咋画啊...

好多小伙伴可能看到这个图,又懵逼了, 你这都啥跟啥啊,一个Glide你画这么几个块就over了?

那网络咋加载的?那缓存怎么处理的,那线程咋切换的?那生命周期咋控制的。啥也没说啊..

各位,各位,先别着急。咱们力争的是先 整体再局部,先总览再细分。接下来咱们针对代码进行跟进。

兄台准备好面对疾风了么?

5. Glide调用某一个方法后具体干了什么事?

首先我们拿一个简单的使用进行跟进

Glide.with(context).load("").into(mImageView)

链式调用,我们分解为以下三个方法进行分析。

Glide.with(context)
Glide.with(context).load("")
Glide.with(context).load("").into(mImageView)

5.1. Glide.with(context)具体干了啥?

死亡如风,常伴吾身。我会给你个痛快的!

/**
   * 简单来说该方法进行了以下几步操作
   * 1. Glide 初始化
   * 2. 各种线程池初始化,各种缓存对象初始化
   * 3. Engine初始化,至于Engine是啥,后续我们慢慢介绍
   * 4. RequestManager 初始化
   * 5. 创建透明的fragment,动态监听生命周期
   */
  @NonNull
  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }

 private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // 检测传入的context是否合规
    Preconditions.checkNotNull(context, "You cannot start .....");
    return Glide.get(context).getRequestManagerRetriever();
  }

  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          //如果glide为null则启动检测初始化逻辑
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }
    return glide;
  }

  private static void checkAndInitializeGlide(@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    // 如果已经在初始化中了,则抛异常。
    if (isInitializing) {
      throw new IllegalStateException( "You cannot call Glide.get() in registerComponents(), use the provided Glide instance instead");
    }
    //设置初始化状态
    isInitializing = true;
    initializeGlide(context, generatedAppGlideModule);
    isInitializing = false;
  }

  private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    Context applicationContext = context.getApplicationContext();
...
    //调用GlideBuilder.build()方法进行Glide初始化
    Glide glide = builder.build(applicationContext);
...
   //注册回调
    ap
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值