Glide加载图片流程

glide源码精髓是能学习到很多设计模式,以及对图片的各种处理,首先以源码通读的方式进入到今天的文章。

glide源码是在4.16.0的版本上分析的。 平常我们使用glide时候直接glide.with(activity).load(url).into(imageview)加载图片,基于此,我们顺藤摸瓜看下底层是怎么加载图片的。

glide.with

我们是基于参数是activity的重载方法:

1
2
3
public static RequestManager with(@NonNull Activity activity) {
  return getRetriever(activity).get(activity);
}

先获取RequestManagerRetriever,然后再获取RequestManager:

1
2
3
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  return Glide.get(context).getRequestManagerRetriever();
}

首先调用Glide.get(context)方法,然后通过getRequestManagerRetriever方法获取到RequestManagerRetriever:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context);
      }
    }
  }
  return glide;
}

可以看到该方法是一个静态方法加锁,锁的是所有线程创建glide的实例。如果glide为空,会调用checkAndInitializeGlide方法,猜测是创建glide实例的方法: alt text
此处不允许多次初始化glide对象,通过一个布尔值控制。接着调用了initializeGlide方法:

1
2
3
4
private static void initializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

调用了另外一个initializeGlide方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
private static void initializeGlide(
    @NonNull Context context,
    @NonNull GlideBuilder builder,
    @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    //省略代码
  Context applicationContext = context.getApplicationContext();
  Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
  applicationContext.registerComponentCallbacks(glide);
  Glide.glide = glide;
}

此处省略了通过注解来生成各种配置,其中注解是GlideModule的注解,它是一个编译时注解,通过编译时扫描到该注解,然后生成GeneratedAppGlideModuleImpl类,initializeGlide是通过反射执行GeneratedAppGlideModuleImpl类。最终通过GlideBuilder.build方法来生成glide对象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Glide build(@NonNull Context context) {
  if (sourceExecutor == null) {//访问资源的线程池
    sourceExecutor = GlideExecutor.newSourceExecutor();
  }
  if (diskCacheExecutor == null) {//缓存线程池
    diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
  }
  if (animationExecutor == null) {//动画线程池
    animationExecutor = GlideExecutor.newAnimationExecutor();
  }
  if (memorySizeCalculator == null) {
    memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
  }
  if (connectivityMonitorFactory == null) {
    connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
  }
  if (bitmapPool == null) {
    int size = memorySizeCalculator.getBitmapPoolSize();
    if (size > 0) {
      bitmapPool = new LruBitmapPool(size);
    } else {
      bitmapPool = new BitmapPoolAdapter();
    }
  }
  if (arrayPool == null) {
    arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
  }
  if (memoryCache == null) {
    memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
  }
  if (diskCacheFactory == null) {
    diskCacheFactory = new InternalCacheDiskCacheFactory(context);
  }
  if (engine == null) {
    engine =
        new Engine(
            memoryCache,
            diskCacheFactory,
            diskCacheExecutor,
            sourceExecutor,
            GlideExecutor.newUnlimitedSourceExecutor(),
            GlideExecutor.newAnimationExecutor(),
            isActiveResourceRetentionAllowed);
  }
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory);
  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptions.lock(),
      defaultTransitionOptions);
}

初始化线程池,构造了Engine、RequestManagerRetriever对象,最后初始化了Glide对象。所以上面的getRequestManagerRetriever方法返回的对象就是此处new的RequestManagerRetriever对象。接着调用了RequestManagerRetriever的get方法:

Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy