Glide配置
懒加载配置
从Glide3.5开始,你可以使用GlideModule
接口来懒加载配置Glide以及注册组件(如ModelLoaders
),这些配置将会在第一个Glide请求发起的时候被调用。
创建一个GlideModule
为了使用和注册GlideModule,首先需要实现该接口,加入你的配置和组件。
package com.mypackage;
public class MyGlideModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
}
@Override public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
然后,添加你的实现类到proguard.cfg
文件中,让你的module可以被反射调用到。这个性能开支很少,因为每个module只会在Glide第一次请求的时候实例化一次。
-keepnames class com.mypackage.MyGlideModule
# or more generally:
#-keep public class * implements com.bumptech.glide.module.GlideModule
最后,添加meta-data标记到AndroidManifest.xml
,那样Glide才能找到它。
<manifest ...>
<!-- ... permissions -->
<application ...>
<meta-data
android:name="com.mypackage.MyGlideModule"
android:value="GlideModule" />
<!-- ... activities and other components -->
</application>
</manifest>
你可以实现任意个GlideModule
,但是每一个都要添加到proguard.cfg
,而且每一个GlideModule都要在manifest有自己的meta-data标记。
Library工程
Library工程可能含有一个或多个GlideModule
。当我们使用Gradle(或者任何支持manifest合并的构建工具)构建app时,如果我们所依赖的Library工程的manifest中含有module,那么这些module会自动并入到app中。如果构建工具不支持manifest合并,那么这些library工程中的module必须手动添加到你app的manifest中。
GlideModule冲突
虽然Glide允许每个app注册多个Glidemodule
,但是不会以某种特定的顺序调用这些module。所以,如果你的app中多个GlideModules
或者依赖的library工程中有多个GlideModules
,你必须负责避免他们之间的冲突。
如果冲突不可避免,app应该定义自己的默认module,这个module需要手动解决这些冲突,提供所有Library工程所需要的依赖。使用Gradle的开发者,或者使用manifest合并的开发者,可以通过下面的标签来排除冲突的module。
<meta-data android:name=”com.mypackage.MyGlideModule” tools:node=”remove” />
全局配置
你可以配置一些作用于所有请求的全局性配置项。请使用GlideModule#applyOptions
方法中(注:作为参数)提供给你的GlideBuilder
来配置。本节代码示例中的builder
就是一个GlideModule对象。
磁盘缓存
你可以使用GlideBuilder
的setDiskCache()
方法设置磁盘缓存的位置、大小(最大值)。你也可以使用DiskCacheAdapter
彻底关闭缓存,或者自己实现DiskCache
接口来换掉默认实现。磁盘缓存由DiskCache.Factory
接口的实例在后台线程中创建,使用后台线程可以避免在严格模式中出现问题。
Glide默认使用InternalCacheDiskCacheFactory
类建立磁盘缓存。这个内部缓存工厂(internal cache factory)会把磁盘缓存放到应用程序的内部缓存目录中,并且设置最大空间是250MB,使用内部缓存的目录而不是SD卡的外部目录意味着其他应用程序无法访问到你下载的图片。具体请查看Android的存储选项相关文档。
大小
使用InternalCacheDiskCacheFactory
设置磁盘缓存大小
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, yourSizeInBytes));
位置
也可以设置磁盘缓存位置
你可以使用InternalCacheDiskCacheFactory
来把你的磁盘缓存放到应用程序私有的内部存储目录中:
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));
还可以用ExternalCacheDiskCacheFactory
来把你的磁盘缓存放到sd卡的公共缓存目录上。
builder.setDiskCache(
new ExternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));
如果你想用其他自定义的路径,可以用DiskLruCacheFactory
类的构造函数来实现。
// If you can figure out the folder without I/O:
// Calling Context and Environment class methods usually do I/O.
builder.setDiskCache(
new DiskLruCacheFactory(getMyCacheLocationWithoutIO(), yourSizeInBytes));
// In case you want to specify a cache folder ("glide"):
builder.setDiskCache(
new DiskLruCacheFactory(getMyCacheLocationWithoutIO(), "glide", yourSizeInBytes));
// In case you need to query the file system while determining the folder:
builder.setDiskCache(new DiskLruCacheFactory(new CacheDirectoryGetter() {
@Override public File getCacheDirectory() {
return getMyCacheLocationBlockingIO();
}
}), yourSizeInBytes);
注意:请牢记,写死任何值都不是个好主意,尤其是目录的路径,因为自Android4.2开始,支持单设备多用户。
如果你想完全控制缓存的创建,可以自己实现DiskCache.Factory
接口,使用DiskLruCacheWrapper
可以在你想要的位置创建一个新的缓存。
builder.setDiskCache(new DiskCache.Factory() {
@Override public DiskCache build() {
File cacheLocation = getMyCacheLocationBlockingIO();
cacheLocation.mkdirs();
return DiskLruCacheWrapper.get(cacheLocation, yourSizeInBytes);
}
});
内存缓存和缓存池
GlideBuilder
类允许你设置内存缓存大小,而且可以实现自定义的MemoryCache
和BitmapPool
。
大小
默认大小是由MemorySizeCalculator
类决定的。MemorySizeCalculator类会考虑该设备的屏幕大小、可用内存来计算出一个合理的默认值。如果你想调整这个默认值,请构建自己的实例。
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
如果你想在应用的某个阶段动态调整Glide的内存占用,你可以选择一个MemoryCategory
并使用setMemoryCategory()
方法传入Glide中:
Glide.get(context).setMemoryCategory(MemoryCategory.HIGH);
内存缓存
Glide的内存缓存会在内存中持有资源,它的作用是,我们可以不进行IO操作而快速获得可用资源。
你可以使用GlideBuilder
的setMemoryCache()
方法设置大小,或者设置你关于内存缓存的自定义实现(自定义类)。LruResourceCache
类是Glide的默认实现。你可以通过LruResourceCache
的构造函数来配置内存占用的bytes的最大值。
builder.setMemoryCache(new LruResourceCache(yourSizeInBytes));
Bitmap池
Glide的Bitmap池主要作用是,可以让各种尺寸的Bitmap被复用,可以可观地减少由垃圾回收引起的内存抖动。在解码图片时,需要给像素数组分配空间,这会触发垃圾回收。
你可以使用GlideBuilder
的setBitmapPool()
方法设置大小,或者设置你关于Bitmap池的自定义实现,LruBitmapPool
类是Glide的默认实现。LruBitmapPool类使用了LRU算法维护最近最常使用的Bitmap的尺寸。你可以通过LruBitmapPool
的构造函数配置内存占用的bytes的最大值。
builder.setBitmapPool(new LruBitmapPool(sizeInBytes));
Bitmap格式
GlideBuilder
类也允许你配置一个App全局使用的Bitmap的Config属性。
Glide默认使用RGB_565,因为它每个像素只需要2bytes(16bit)的空间,它仅需要高质量图片(既系统默认的ARGB_8888
)一半的内存空间。但是,这对于某些图片这可能会出现『条带』的问题,而且它也不支持透明度。
如果在你的应用中『条带』是一个重要的问题,或者你需要尽可能好的图片质量,你可以使用GlideBuilder
的setDecodeFormat
方法设置DecodeFormat.ALWAYS_ARGB_8888作为首选配置。
builder.setDecodeFormat(DecodeFormat.ALWAYS_ARGB_8888);