Glide源码学习七:自定义模块功能(1)

在标签中加入一个meta-data配置项,其中android:name指定成我们自定义的MyGlideModule的完整路径,android:value必须指定成GlideModule,这个是固定值。

这样的话,我们就将Glide自定义模块的功能完成了,是不是非常简单?现在Glide已经能够识别我们自定义的这个MyGlideModule了,但是在编写具体的功能之前,我们还是按照老规矩阅读一下源码,从源码的层面上来分析一下,Glide到底是如何识别出这个自定义的MyGlideModule的。

自定义模块的原理

========

显然我们已经用惯了Glide.with(context).load(url).into(imageView)这样一行简洁的Glide图片加载语句,但是我们好像从来没有注意过Glide这个类本身的实例。然而事实上,Glide类确实是有创建实例的,只不过是在内部由Glide自动帮我们创建和管理了,对于开发者而言,大多数情况下是不用关心它的,只需要调用它的静态方法就可以了。

那么Glide的实例到底是在哪里创建的呢?我们来看下Glide类中的get()方法的源码,如下所示:

public class Glide {

private static volatile Glide glide;

public static Glide get(Context context) {

if (glide == null) {

synchronized (Glide.class) {

if (glide == null) {

Context applicationContext = context.getApplicationContext();

List modules = new ManifestParser(applicationContext).parse();

GlideBuilder builder = new GlideBuilder(applicationContext);

for (GlideModule module : modules) {

module.applyOptions(applicationContext, builder);

}

glide = builder.createGlide();

for (GlideModule module : modules) {

module.registerComponents(applicationContext, glide);

}

}

}

}

return glide;

}

}

我们来仔细看一下上面这段代码。首先这里使用了一个单例模式来获取Glide对象的实例,可以看到,这是一个非常典型的双重锁模式。然后在第12行,调用ManifestParser的parse()方法去解析AndroidManifest.xml文件中的配置,实际上就是将AndroidManifest中所有值为GlideModule的meta-data配置读取出来,并将相应的自定义模块实例化。由于你可以自定义任意多个模块,因此这里我们将会得到一个GlideModule的List集合。

接下来在第13行创建了一个GlideBuilder对象,并通过一个循环调用了每一个GlideModule的applyOptions()方法,同时也把GlideBuilder对象作为参数传入到这个方法中。而applyOptions()方法就是我们可以加入自己的逻辑的地方了,虽然目前为止我们还没有编写任何逻辑。

再往下的一步就非常关键了,这里调用了GlideBuilder的createGlide()方法,并返回了一个Glide对象。也就是说,Glide对象的实例就是在这里创建的了,那么我们跟到这个方法当中瞧一瞧:

public class GlideBuilder {

private final Context context;

private Engine engine;

private BitmapPool bitmapPool;

private MemoryCache memoryCache;

private ExecutorService sourceService;

private ExecutorService diskCacheService;

private DecodeFormat decodeFormat;

private DiskCache.Factory diskCacheFactory;

Glide createGlide() {

if (sourceService == null) {

final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());

sourceService = new FifoPriorityThreadPoolExecutor(cores);

}

if (diskCacheService == null) {

diskCacheService = new FifoPriorityThreadPoolExecutor(1);

}

MemorySizeCalculator calculator = new MemorySizeCalculator(context);

if (bitmapPool == null) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

int size = calculator.getBitmapPoolSize();

bitmapPool = new LruBitmapPool(size);

} else {

bitmapPool = new BitmapPoolAdapter();

}

}

if (memoryCache == null) {

memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());

}

if (diskCacheFactory == null) {

diskCacheFactory = new InternalCacheDiskCacheFactory(context);

}

if (engine == null) {

engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);

}

if (decodeFormat == null) {

decodeFormat = DecodeFormat.DEFAULT;

}

return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);

}

}

这个方法中会创建BitmapPool、MemoryCache、DiskCache、DecodeFormat等对象的实例,并在最后一行创建一个Glide对象的实例,然后将前面创建的这些实例传入到Glide对象当中,以供后续的图片加载操作使用。

但是大家有没有注意到一个细节,createGlide()方法中创建任何对象的时候都做了一个空检查,只有在对象为空的时候才会去创建它的实例。也就是说,如果我们可以在applyOptions()方法中提前就给这些对象初始化并赋值,那么在createGlide()方法中就不会再去重新创建它们的实例了,从而也就实现了更改Glide配置的功能。关于这个功能我们待会儿会进行具体的演示。

现在继续回到Glide的get()方法中,得到了Glide对象的实例之后,接下来又通过一个循环调用了每一个GlideModule的registerComponents()方法,在这里我们可以加入替换Glide的组件的逻辑。

好了,这就是Glide自定义模块的全部工作原理。了解了它的工作原理之后,接下来所有的问题就集中在我们到底如何在applyOptions()和registerComponents()这两个方法中加入具体的逻辑了,下面我们马上就来学习一下。

更改Glide配置

=========

刚才在分析自定义模式工作原理的时候其实就已经提到了,如果想要更改Glide的默认配置,其实只需要在applyOptions()方法中提前将Glide的配置项进行初始化就可以了。那么Glide一共有哪些配置项呢?这里我给大家做了一个列举:

  • setMemoryCache()     用于配置Glide的内存缓存策略,默认配置是LruResourceCache。

  • setBitmapPool()      用于配置Glide的Bitmap缓存池,默认配置是LruBitmapPool。

  • setDiskCache()       用于配置Glide的硬盘缓存策略,默认配置是InternalCacheD

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值