Glide的自定义模块
自定义模块功能可以将更改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/