• Glide 源码解析与原理总结——Glide.with


    写作背景

    Glide 作为著名的图片加载框架,几乎每一个项目都使用到。笔者尝试通过别人的博客来了解 Glide 原理,但是每次都是看着看着就懵逼了,不是因为别人写的不好,而是 Glide 实在是太复杂了,于是决定自己撸一遍,加深印象。纸上得来终觉浅,绝知此事要躬行。

    因为 Glide 太庞大了,做不到面面俱到,所以笔者主要先梳理主干核心原理,后续持续整理。本文源码分析基于4.15.0,就从最基础的调用 Glide.with(context).load(url).into(imageView) 来入手,把主流程最核心的源码整理并且标注、总结。

    该篇是Glide.with

    Glide.with 源码分析

    作用
    Glide负责线程池、缓存的构建
    RequestManagerRetriever负责获取RequestManager
    SupportRequestManagerFragment用户接收和转发生命周期
    RequestManager用于请求管理

    第1步,从 Glide.with 出发,可以看到Glide.with 有很多重载方法,目的是返回一个RequestManager。(Glide.java)

    1. //传递Context
    2. public static RequestManager with(@NonNull Context context) {
    3. return getRetriever(context).get(context);
    4. }
    5. // 传递FragmentActivity
    6. public static RequestManager with(@NonNull FragmentActivity activity) {
    7. return getRetriever(activity).get(activity);
    8. }
    9. // 传递Fragment
    10. public static RequestManager with(@NonNull Fragment fragment) {
    11. return getRetriever(fragment.getContext()).get(fragment);
    12. }
    13. //传递View
    14. public static RequestManager with(@NonNull View view) {
    15. return getRetriever(view.getContext()).get(view);
    16. }
    17. ......

    第2步 Glide.with 里面会调用 getRetriever方法,getRetriever() 先会调用 Glide.get(),Glide.get 会调用checkAndInitializeGlide 方法,注意会传递一个APT生成的 GeneratedAppGlideModuleImpl(Glide.java)

    1. private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    2. // 省略...
    3. return Glide.get(context).getRequestManagerRetriever();
    4. }
    5. //双层检测单例模式
    6. public static Glide get(@NonNull Context context) {
    7. if (glide == null) {
    8. //getAnnotationGeneratedGlideModules 内部通过。
    9. //Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl")
    10. //拿到GeneratedAppGlideModuleImpl 并且作为参数传递
    11. GeneratedAppGlideModule annotationGeneratedModule =
    12. getAnnotationGeneratedGlideModules(context.getApplicationContext());
    13. synchronized (Glide.class) {
    14. if (glide == null) {
    15. checkAndInitializeGlide(context, annotationGeneratedModule);
    16. }
    17. }
    18. }
    19. return glide;
    20. }

    最终来到Glide.initializeGlide,GeneratedAppGlideModuleImpl 的作用先记录,后续再慢慢了解,因为 Glide 内容实在太庞大了,每一个细节都要掌握无法梳理主流程(Glide.java)

    1. private static void initializeGlide(
    2. @NonNull Context context,
    3. @NonNull GlideBuilder builder,
    4. @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    5. //1. 获取应用AppContext,最终是用来构建Glide的
    6. Context applicationContext = context.getApplicationContext();
    7. //2.这里通过传递进来的 GeneratedAppGlideModuleImpl 调用 getExcludedModuleClasses
    8. List manifestModules = Collections.emptyList();
    9. if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    10. manifestModules = new ManifestParser(applicationContext).parse();
    11. }
    12. if (annotationGeneratedModule != null
    13. && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
    14. Set> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
    15. Iterator iterator = manifestModules.iterator();
    16. while (iterator.hasNext()) {
    17. GlideModule current = iterator.next();
    18. if (!excludedModuleClasses.contains(current.getClass())) {
    19. continue;
    20. }
    21. if (Log.isLoggable(TAG, Log.DEBUG)) {
    22. Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
    23. }
    24. iterator.remove();
    25. }
    26. }
    27. if (Log.isLoggable(TAG, Log.DEBUG)) {
    28. for (GlideModule glideModule : manifestModules) {
    29. Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
    30. }
    31. }
    32. //3.这里通过传递进来的 GeneratedAppGlideModuleImpl 获取 RequestManagerRetriever.RequestManagerFactory
    33. RequestManagerRetriever.RequestManagerFactory factory =
    34. annotationGeneratedModule != null
    35. ? annotationGeneratedModule.getRequestManagerFactory()
    36. : null;
    37. //4.将拿到的工厂添加到GlideBuilder
    38. builder.setRequestManagerFactory(factory);
    39. for (GlideModule module : manifestModules) {
    40. module.applyOptions(applicationContext, builder);
    41. }
    42. //5.这里通过传递进来的 GeneratedAppGlideModuleImpl 调用 applyOptions
    43. if (annotationGeneratedModule != null) {
    44. annotationGeneratedModule.applyOptions(applicationContext, builder);
    45. }
    46. //6.通过GlideBuilder 建造者模式生成 Glide
    47. Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
    48. applicationContext.registerComponentCallbacks(glide);
    49. //7. 将构建出来的glide 赋值给 Glide 的静态变量
    50. Glide.glide = glide;
    51. }

    第3步,我们看到了有一个GlideBuilder 来生成Glide,这里有一个地方非常关键:GliderBuilder 来构建Glide,传递的Context 是applicationContext!!!, 你外部使用activity, 这里都会getApplicationContext 传入!!! 

    1. Glide build(
    2. @NonNull Context context,
    3. List manifestModules,
    4. AppGlideModule annotationGeneratedGlideModule) {
    5. //实例化网络请求线程池
    6. if (sourceExecutor == null) {
    7. sourceExecutor = GlideExecutor.newSourceExecutor();
    8. }
    9. //实例化磁盘缓存线程池
    10. if (diskCacheExecutor == null) {
    11. diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    12. }
    13. //实例化图片加载动画线程池
    14. if (animationExecutor == null) {
    15. animationExecutor = GlideExecutor.newAnimationExecutor();
    16. }
    17. //实例化图片加载内存大小计算器
    18. if (memorySizeCalculator == null) {
    19. memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    20. }
    21. //实例化网络连接监控工厂
    22. if (connectivityMonitorFactory == null) {
    23. connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    24. }
    25. //实例化Bitmap对象池
    26. if (bitmapPool == null) {
    27. int size = memorySizeCalculator.getBitmapPoolSize();
    28. if (size > 0) {
    29. bitmapPool = new LruBitmapPool(size);
    30. } else {
    31. bitmapPool = new BitmapPoolAdapter();
    32. }
    33. }
    34. //实例化数组对象池
    35. if (arrayPool == null) {
    36. arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    37. }
    38. //实例化内存缓存 LruCache
    39. if (memoryCache == null) {
    40. memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    41. }
    42. //实例化磁盘缓存工厂
    43. if (diskCacheFactory == null) {
    44. diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    45. }
    46. //构建执行缓存策略跟线程池的引擎
    47. if (engine == null) {
    48. engine =
    49. new Engine(
    50. memoryCache,
    51. diskCacheFactory,
    52. diskCacheExecutor,
    53. sourceExecutor,
    54. GlideExecutor.newUnlimitedSourceExecutor(),
    55. animationExecutor,
    56. isActiveResourceRetentionAllowed);
    57. }
    58. if (defaultRequestListeners == null) {
    59. defaultRequestListeners = Collections.emptyList();
    60. } else {
    61. defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    62. }
    63. GlideExperiments experiments = glideExperimentsBuilder.build();
    64. //实例化RequestManagerRetriever 请求管理类
    65. RequestManagerRetriever requestManagerRetriever =
    66. new RequestManagerRetriever(requestManagerFactory);
    67. //实例化Glide
    68. return new Glide(
    69. context,
    70. engine,
    71. memoryCache,
    72. bitmapPool,
    73. arrayPool,
    74. requestManagerRetriever,
    75. connectivityMonitorFactory,
    76. logLevel,
    77. defaultRequestOptionsFactory,
    78. defaultTransitionOptions,
    79. defaultRequestListeners,
    80. manifestModules,
    81. annotationGeneratedGlideModule,
    82. experiments);
    83. }

    第4步,所以首次调用 Glide.get() 会把 Glide 构建完成,那么调用 Glide 的 getRequestManagerRetriver()就能拿到 RequestManagerRetriver对象。下面看看RequestManagerRetriver.get() 方法,也是有很多重载方法。

     先看下RequestManagerRetriver.get(Context context), 可以看到如果不在主线程或者Context为AppContext,那么调用的是getApplicationManager

    1. @NonNull
    2. public RequestManager get(@NonNull Context context) {
    3. if (context == null) {
    4. throw new IllegalArgumentException("You cannot start a load on a null Context");
    5. } else if (Util.isOnMainThread() && !(context instanceof Application)) {//1.主线程并且context不为Application
    6. if (context instanceof FragmentActivity) {
    7. //2.如果是FragmentActivity
    8. return get((FragmentActivity) context);
    9. } else if (context instanceof Activity) {
    10. //3.如果是Activity
    11. return get((Activity) context);
    12. } else if (context instanceof ContextWrapper
    13. && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
    14. //4.如果是ContextWrapper,并且baseContext的AppContext 不为空
    15. return get(((ContextWrapper) context).getBaseContext());
    16. }
    17. }
    18. //5.不在主线程或者context为AppContext 调用getApplicationManager
    19. return getApplicationManager(context);
    20. }

    第5步,先看getApplicationManager(context) 构建applicationManager的对象, 这个是App层级的RequestManager。 (RequestManagerReceiver.java)

    1. private RequestManager getApplicationManager(@NonNull Context context) {
    2. // Either an application context or we're on a background thread.
    3. if (applicationManager == null) {
    4. synchronized (this) {
    5. if (applicationManager == null) {
    6. //使用AppContext 作为参数拿Glide
    7. Glide glide = Glide.get(context.getApplicationContext());
    8. applicationManager =
    9. factory.build(
    10. glide,
    11. new ApplicationLifecycle(),//注意:这里是ApplicationLifecycle
    12. new EmptyRequestManagerTreeNode(),
    13. context.getApplicationContext());
    14. }
    15. }
    16. }
    17. return applicationManager;//返回RequestManager
    18. }

     第6步,再看看传递Activity 的情况, 最终会调用FragmentGet 生成一个Fragment 来监听生命周期。这里是最重要的一个方法

    1. public RequestManager get(@NonNull Activity activity) {
    2. if (Util.isOnBackgroundThread()) {
    3. return get(activity.getApplicationContext());
    4. } else if (activity instanceof FragmentActivity) {
    5. return get((FragmentActivity) activity);
    6. } else {
    7. assertNotDestroyed(activity);
    8. frameWaiter.registerSelf(activity);
    9. android.app.FragmentManager fm = activity.getFragmentManager();
    10. //注意:调用FragmentGet,这里会生成一个Fragment 用来监听生命周期
    11. return fragmentGet(activity, fm, /* parentHint= */ null, isActivityVisible(activity));
    12. }
    13. }

    第7步 , fragmentGet 方法生成空白的Fragment,该Fragment 是用来管理请求的生命周期的,并且会和RequestManagerFactory工厂生成的RequestManager 绑定。

    1. private RequestManager fragmentGet(
    2. @NonNull Context context,
    3. @NonNull android.app.FragmentManager fm,
    4. @Nullable android.app.Fragment parentHint,
    5. boolean isParentVisible) {
    6. //1. 通过getRequestManagerFragment生成一个空白的Fragment,用来管理请求的生命周期,核心方法!!
    7. RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    8. RequestManager requestManager = current.getRequestManager();
    9. //2. 如果FragmentManager,为空,就用RequestManagerFactory工厂生成一个并且设给RequestManagerFragment
    10. if (requestManager == null) {
    11. Glide glide = Glide.get(context);
    12. requestManager =
    13. factory.build(
    14. glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    15. if (isParentVisible) {
    16. requestManager.onStart();
    17. }
    18. current.setRequestManager(requestManager);
    19. }
    20. //3. 返回RequestManager
    21. return requestManager;
    22. }

    第8步 在看工厂如何生成FragmentManager 之前,先看看如何生成空白的Fragment——RequestManagerFragment,因为这个RequestManagerFragment最终要和RequestManager 绑定的。

    1. private RequestManagerFragment getRequestManagerFragment(
    2. @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
    3. //1. 先缓存中取
    4. RequestManagerFragment current = pendingRequestManagerFragments.get(fm);
    5. //2.缓存里面没有,再通过 TAG 从FragmentManager 里拿
    6. if (current == null) {
    7. current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    8. //3. 缓存没有,通过TAG 也拿不到,就初始化一个新的
    9. if (current == null) {
    10. current = new RequestManagerFragment();
    11. current.setParentFragmentHint(parentHint);
    12. //4. 先放入缓存,以免下一次Glide请求会再生成一个空白的Fragment
    13. pendingRequestManagerFragments.put(fm, current);
    14. //5. 通过当前 Activity的 FragmentManager 开始提交添加一个 Fragment容器
    15. fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
    16. //6. 这个空白的Fragment 添加到 FragmentManager 成功,通过 Handler 发送一个消息,清理缓存
    17. handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
    18. }
    19. }
    20. return current;
    21. }

    上面的 getRequestManagerFragment 有一个很重要的点:采用了双重检测保证宿主、空白Fragment、RequestManager 一一对应

    第一重保障:使用Map保存记录集合,解决多个请求只有一个空白Fragment

    第二重保障:通过Handler 发送消息让空白的Fragment 马上添加到FragmentManager

    FragmentManager 的事务本来就是通过Handler 发送消息来实现,通过Handler 发送消息有可能不会被马上执行,倘若空白的Fragment的消息一直在等待,那么下一次Glide请求就会再生成一个空白的Fragment。而通过Handler 发送删除消息,可以让空白的Fragment添加到FragmentManager马上执行并且清空缓存,这样下一次Glide 请求到来的时候,从FragmentManager的TAG 就能拿到Fragment, 不会再创建。

     第9步,我们再回过头来看看怎样通过工厂RequestManagerFactory 来生成RequestManager的

    1. private static final RequestManagerFactory DEFAULT_FACTORY =
    2. new RequestManagerFactory() {
    3. @NonNull
    4. @Override
    5. public RequestManager build(
    6. @NonNull Glide glide,
    7. @NonNull Lifecycle lifecycle,
    8. @NonNull RequestManagerTreeNode requestManagerTreeNode,
    9. @NonNull Context context) {
    10. //工厂里也是new 一个 RequestManager
    11. return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    12. }
    13. };

      第10步,RequestManager 初始化,监听lifecycle的生命周期。而这个lifecycl就是空白Fragment里的ActivityFragmentLifecycle

    1. RequestManager(
    2. Glide glide,
    3. Lifecycle lifecycle,
    4. RequestManagerTreeNode treeNode,
    5. RequestTracker requestTracker,
    6. ConnectivityMonitorFactory factory,
    7. Context context) {
    8. this.glide = glide;
    9. this.lifecycle = lifecycle;
    10. this.treeNode = treeNode;
    11. this.requestTracker = requestTracker;
    12. this.context = context;
    13. connectivityMonitor =
    14. factory.build(
    15. context.getApplicationContext(),
    16. new RequestManagerConnectivityListener(requestTracker));
    17. glide.registerRequestManager(this);
    18. if (Util.isOnBackgroundThread()) {
    19. Util.postOnUiThread(addSelfToLifecycle);
    20. } else {
    21. lifecycle.addListener(this);//this 就是RequestManager 因此RequestManager就会监听Lifecycle生命周期
    22. }
    23. lifecycle.addListener(connectivityMonitor);
    24. defaultRequestListeners =
    25. new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    26. setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
    27. }
    28. //Requestmanager 已经监听了空白Fragment的lifecycle
    29. @Override
    30. public synchronized void onStart() {
    31. resumeRequests();//恢复请求
    32. targetTracker.onStart();
    33. }
    34. @Override
    35. public synchronized void onStop() {
    36. pauseRequests();//暂停请求
    37. targetTracker.onStop();
    38. }

    1. public class RequestManagerFragment extends Fragment {
    2. private static final String TAG = "RMFragment";
    3. private final ActivityFragmentLifecycle lifecycle;
    4. ......
    5. @Override
    6. public void onStart() {
    7. super.onStart();
    8. lifecycle.onStart();//转发生命周期
    9. }
    10. @Override
    11. public void onStop() {
    12. super.onStop();
    13. lifecycle.onStop();//转发生命周期
    14. }
    15. @Override
    16. public void onDestroy() {
    17. super.onDestroy();
    18. lifecycle.onDestroy();
    19. unregisterFragmentWithRoot();//转发生命周期
    20. }
    21. }

     到此,可以看到 RequestManager 通过监听空白Fragment 的 lifecycle 的生命周期来管理请求的生命周期的。

    Glide.with 原理总结

    Glide 初始化并且生成RequestManager,RequestManager 与 空白Fragment 的 lifecycle 生命周期绑定来管理后续的请求。

    1) 空白Fragment 持有ActivityFragmentLifecycle,当空白Fragment生命周期改变的时候,调用onStart()、onStop()、onDestroy()——>

    2)ActivityFragmentLifecycle 持有LifecycleListener集合,其中RequestManager是其中的一个LifecycleListener,ActivityFragmentLifecycle遍历集合,调用LifecycleListener的onStart()、onStop()、onDestroy()——>

    3) RequestManager 实现了LifecycleListener, 在onStart()、onStop()、onDestroy()方法中进行请求的生命周期管理。

  • 相关阅读:
    【SpringBoot】数据访问 —— MySQL
    深入理解JVM笔记
    MIT指出公开预训练模型不能乱用
    axios的封装
    多变量两两相互关系联合分布图的Python绘制
    Android服务器的通信方式
    GS5812B 封装SOT23-6 一款用于无线充电2A , 21V 600KHZ同步降压IC
    django rest framework框架中用到的组件
    开源基于Rust编写的Web服务器
    openMP学习笔记 -编程模型
  • 原文地址:https://blog.csdn.net/xiaobaaidaba123/article/details/134222622