The with process of Glide principle

  This article is based on the Glide4.9.0 version.

 Glide is currently the mainstream image loading framework in Android development. It is necessary to take the time to study how it is implemented. Therefore, starting from this article, the main process of Glide will be analyzed. Since the loading chain of Glide is relatively long, it is easy to understand that we will analyze it separately, and analyze the Glide.with process first.

 1.Glide.with(FragmentActivity)

/**
   * 根据FragmentActivity获取Glide对象,并将加载过程跟FragmentActivity生命周期绑定。
   *
   * @param activity The activity to use.
   * @return A RequestManager for the given FragmentActivity that can be used to start a load.
   */
  @NonNull
  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }

The getRetriever method is called.

2. getRetriever method

@NonNull
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // 检测context空对象,抛出异常
    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();
  }


  /** Internal method. */
  @NonNull
  public RequestManagerRetriever getRequestManagerRetriever() {
    return requestManagerRetriever;
  }

According to the getRequestManagerRetriever method, we found that the RequestManagerRetriever object is a property of the Glide class. Let's see how it is initialized in the get method.

3. Glide.get method

  /**
   * 单例
   *
   * @return the singleton
   */
  @NonNull
  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      //获取注解生成的AppGlideModule
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }

    return glide;
  }

3.1 getAnnotationGeneratedGlideModules

The GeneratedAppGlideModule method instantiates the AppGlideModule object through reflection and returns it.

  @Nullable
  @SuppressWarnings({"unchecked", "TryWithIdenticalCatches", "PMD.UnusedFormalParameter"})
  private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
    GeneratedAppGlideModule result = null;
    try {
      Class<GeneratedAppGlideModule> clazz =
          (Class<GeneratedAppGlideModule>)
              Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
      result =
          clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
    } catch (ClassNotFoundException e) {
      if (Log.isLoggable(TAG, Log.WARN)) {
        Log.w(
            TAG,
            "Failed to find GeneratedAppGlideModule. You should include an"
                + " annotationProcessor compile dependency on com.github.bumptech.glide:compiler"
                + " in your application and a @GlideModule annotated AppGlideModule implementation"
                + " or LibraryGlideModules will be silently ignored");
      }
      // These exceptions can't be squashed across all versions of Android.
    } catch (InstantiationException e) {
      throwIncorrectGlideModule(e);
    } catch (IllegalAccessException e) {
      throwIncorrectGlideModule(e);
    } catch (NoSuchMethodException e) {
      throwIncorrectGlideModule(e);
    } catch (InvocationTargetException e) {
      throwIncorrectGlideModule(e);
    }
    return result;
  }

4. checkAndInitializeGlide

Before the get method returns the Glide instance, it needs to perform some initialization operations in the checkAndInitializaGlide method.

@GuardedBy("Glide.class")
  private static void checkAndInitializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    // In the thread running initGlide(), one or more classes may call Glide.get(context).
    // Without this check, those calls could trigger infinite recursion.
    //加入状态为控制并发初始化的情况
    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;
  }

5. initializeGlide(context, generatedAppGlideModule)

  @GuardedBy("Glide.class")
  private static void initializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
  }

  @GuardedBy("Glide.class")
  @SuppressWarnings("deprecation")
  private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    Context applicationContext = context.getApplicationContext();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    //1.注解生成的Module为空或者支持解析Manifest配置的Module,则创建ManifestParser解析Manifest中配置的Module
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }
    //2.如果有注解生成的Module且屏蔽的Module集合不为空,则过率Manifest中配置的Module。
    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
      Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
      Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
      while (iterator.hasNext()) {
        com.bumptech.glide.module.GlideModule current = iterator.next();
        if (!excludedModuleClasses.contains(current.getClass())) {
          continue;
        }
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
        }
        iterator.remove();
      }
    }

    if (Log.isLoggable(TAG, Log.DEBUG)) {
      for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
        Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
      }
    }
    //3.初始化RequestManager的工厂对象,赋值给GlideBuilder
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    builder.setRequestManagerFactory(factory);
    //4.依次回调用外部配置的Module中的applyOptions方法,实现GlideBuilder配置的修改。
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    //5.创建Glide对象
    Glide glide = builder.build(applicationContext);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      try {
        module.registerComponents(applicationContext, glide, glide.registry);
      } catch (AbstractMethodError e) {
        throw new IllegalStateException(
            "Attempting to register a Glide v3 module. If you see this, you or one of your"
                + " dependencies may be including Glide v3 even though you're using Glide v4."
                + " You'll need to find and remove (or update) the offending dependency."
                + " The v3 module name is: "
                + module.getClass().getName(),
            e);
      }
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    //6. 注册Application 生命周期监听。内存紧张时把BitmapPool、MemoryCache和ArrayPool都清空
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

 

6. GlideBuilder.build()

public final class GlideBuilder {
  //图片转换处理集合
  private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions = new ArrayMap<>();
  //图片加载引擎,负责启动并管理缓存资源
  private Engine engine;
  //Lru策略的图片池,内存不足时自动清空
  private BitmapPool bitmapPool;
  //Lru策略的数组池,用于读写IO,内存不足时自动清空
  private ArrayPool arrayPool;
  // Lru策略的内存缓存池,内存不足时自动清空
  private MemoryCache memoryCache;
  //线程池,用于查找内存缓存,最大线程数为4,具体取决于cpu
  private GlideExecutor sourceExecutor;
  //线程池,用于查找本地磁盘缓存,最大线程数为4,具体取决于cpu
  private GlideExecutor diskCacheExecutor;
  //用于创建本地磁盘缓存对象的工厂,默认本地磁盘缓存size为250M 
  private DiskCache.Factory diskCacheFactory;
  //内存计算器,它通过获取手机硬件常量和手机的屏幕密度、宽度和长度来计算出最适合当前情况的内存缓存的大小
  private MemorySizeCalculator memorySizeCalculator;
  //用于生产网络状态监听事件的工厂
  private ConnectivityMonitorFactory connectivityMonitorFactory;
  private int logLevel = Log.INFO;
  //设置Glide的配置选项
  private RequestOptionsFactory defaultRequestOptionsFactory =
      new RequestOptionsFactory() {
        @NonNull
        @Override
        public RequestOptions build() {
          return new RequestOptions();
        }
      };
  //用于创建RequestManager对象的工厂
  @Nullable private RequestManagerFactory requestManagerFactory;
  //线程池,用于加载gif图片,默认线程数为1~2,最大数取决于cpu的核数
  private GlideExecutor animationExecutor;
  // 是否将保留图片资源数据不给回收,默认为false 需要注意的是,设为true将会导致更大的内存消耗,增加crash的几率
  private boolean isActiveResourceRetentionAllowed;
  //全局网络请求集合,每次网络请求都会回调
  @Nullable private List<RequestListener<Object>> defaultRequestListeners;

  //...省略部分代码

  @NonNull
  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(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }
    //实例化RequestManagerRetriever对象,RequestManagerRetriever 是 Handler.CallBack 实现类,同时也是生命周期的一个管理类
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps,
        hardwareBitmapFdLimit);
  }
}

7. RequestManagerRetriever.get(FragmentActivity)

RequestManagerRetriever It is  Handler.CallBack an implementation class and also a management class of the life cycle .

  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
    //是否在子线程运行
    if (Util.isOnBackgroundThread()) {
      //暂时忽略子线程启动的流程
      return get(activity.getApplicationContext());
    } else {
      //检查Activity是否被销毁
      assertNotDestroyed(activity);
      FragmentManager fm = activity.getSupportFragmentManager();
      //
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

8.RequestManagerRetriever.supportFragmentGet


  @NonNull
  private RequestManager supportFragmentGet(
      @NonNull Context context,
      @NonNull FragmentManager fm,
      @Nullable Fragment parentHint,
      boolean isParentVisible) {
    //获取监控FragmentActivity生命周期的Fragment
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    //获取SupportRequestManagerFragment中的RequestManager对象
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call.
      Glide glide = Glide.get(context);
      //为空,重新创建一个并存到SupportRequestManagerFragment
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }


  @NonNull
  private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    //查找SupportRequestManagerFragment
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      //若为空从缓存中取
      current = pendingSupportRequestManagerFragments.get(fm);
      if (current == null) {
        //依然为空则重新创建一个
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        //若Activity可见,回调生命周期监听
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        //缓存起来
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        //发送消息,清空刚存进去的Fragment,这个地方没太理解为什么这样搞
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

Created a RequestManager that uses DEFAULT_FACTORY by default

private static final RequestManagerFactory DEFAULT_FACTORY =
      new RequestManagerFactory() {
        @NonNull
        @Override
        public RequestManager build(
            @NonNull Glide glide,
            @NonNull Lifecycle lifecycle,
            @NonNull RequestManagerTreeNode requestManagerTreeNode,
            @NonNull Context context) {
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };

At this point, Glide the  with(FragmentActivity) process analysis is completed. Next, analyze the load process

Guess you like

Origin blog.csdn.net/gjd1988/article/details/100080555