Glide的自定义模块

2021-03-30  本文已影响0人  风月寒

自定义模块功能可以将更改Glide配置,替换Glide组件等操作独立出来,使得我们能轻松地对Glide的各种配置进行自定义,并且又和Glide的图片加载逻辑没有任何交集。

首先我们需要定义一个实现类,来继承我们的AppGlideModule.必须加上@GlideModule注解。这是根据Glide4.9版本写的,跟3.7的有差别。

@GlideModule
public class MyGlideModule extends AppGlideModule {
    
    
}

public abstract class AppGlideModule extends LibraryGlideModule implements AppliesOptions {
 
  public boolean isManifestParsingEnabled() {
    return true;
  }

  @Override
  public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
    // Default empty impl.
  }
}

public abstract class LibraryGlideModule implements RegistersComponents {
  @Override
  public void registerComponents(@NonNull Context context, @NonNull Glide glide,
      @NonNull Registry registry) {
    
  }
}

然后里面有两个需要实现的方法。applyOptions()和registerComponents()。这两个方法分别就是用来更改Glide配置以及替换Glide组件的。

然后需要在manifest注册。

<meta-data android:name="com.example.glidepicasso.fetcher.MyGlideModule"
            android:value="GlideModule"/>

那是这样加载到我们自己定义的组件的?

Glide.with(this)

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

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

public static Glide get(@NonNull Context context) {
        if (glide == null) {
            Class var1 = Glide.class;
            synchronized(Glide.class) {
                if (glide == null) {
                    checkAndInitializeGlide(context);
                }
            }
        }

        return glide;
    }

当我们调用with的时候,会先创建一个glide对象。

private static void checkAndInitializeGlide(@NonNull Context context) {
        if (isInitializing) {
            throw new IllegalStateException("You cannot call Glide.get() in registerComponents(), use the provided Glide instance instead");
        } else {
            isInitializing = true;
            initializeGlide(context);
            isInitializing = false;
        }
    }
private static void initializeGlide(@NonNull Context context) {
        initializeGlide(context, new GlideBuilder());
    }
    
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();//1
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();//2
    }

    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {//3
      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();
      }
    }

    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory() : null;//4
    builder.setRequestManagerFactory(factory);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    Glide glide = builder.build(applicationContext);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.registerComponents(applicationContext, glide, glide.registry);//5
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

先看1处,解析注解,即添加@GlideModule的注解,

private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules() {
    GeneratedAppGlideModule result = null;
    try {
      Class<GeneratedAppGlideModule> clazz =
          (Class<GeneratedAppGlideModule>)
              Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
      result = clazz.getDeclaredConstructor().newInstance();
    }
    return result;
  }

通过反射的方式得到GeneratedAppGlideModuleImpl实例,这个类在rebuild的时候会在build/generated/ap_generated_sources/debug/out/com/bumptech.glide/路径下生成。

在2处,isManifestParsingEnabled()返回的是true.

public abstract class AppGlideModule extends LibraryGlideModule implements AppliesOptions {
  
  public boolean isManifestParsingEnabled() {
    return true;
  }

  @Override
  public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
    // Default empty impl.
  }
}

所以会进入if()中。调用ManifestParser对Manifest文件进行解析。

public List<GlideModule> parse() {
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(TAG, "Loading Glide modules");
    }
    List<GlideModule> modules = new ArrayList<>();
    try {
      ApplicationInfo appInfo = context.getPackageManager()
          .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
      if (appInfo.metaData == null) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "Got null app info metadata");
        }
        return modules;
      }
      for (String key : appInfo.metaData.keySet()) {
        if (GLIDE_MODULE_VALUE.equals(appInfo.metaData.get(key))) {
          modules.add(parseModule(key));
          if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Loaded Glide module: " + key);
          }
        }
      }
    } catch (PackageManager.NameNotFoundException e) {
      throw new RuntimeException("Unable to find metadata to parse GlideModules", e);
    }
    return modules;
  }

Manifest文件中的东西都会解析到ApplicationInfo中,所以我们只需要拿到ApplicationInfo中的metaData即可。这里有个判断,就是其value必须是GlideModule。

拿到modules之后便在4处进行注册操作。

关于怎么glide的自定义模块怎么操作看 https://github.com/fengyuehan/Test/tree/master/glidepicasso

使用场景

在原生的glide中请求网络采用的是HttpURLConnection,而我们需要一些需要自己展示加载图片的进度条的时候,一般换成okhttp操作的时候,比较好操作。此时我们就可以采用自定义模块的方式进行操作。

另外具体的api操作可以看下面这两篇文章

http://ocnyang.com/2016/08/17/GlideUse/

http://ocnyang.com/2016/08/09/GlideAbout/

引用文献

http://ocnyang.com/2016/08/17/GlideUse/

http://ocnyang.com/2016/08/09/GlideAbout/

上一篇下一篇

猜你喜欢

热点阅读