Coil 1.x relied on OkHttp's disk cache, however it's no longer needed
从官网的这句话我们可以知道,1.x使用的是okhttp的diskcache。所以我们只需要关注Okhttp创建时候的配置。
简单用法
val request = ImageRequest.Builder(context)
.data(data)
.target(this)
.apply(builder)
.build()
return imageLoader.enqueue(request)
跟踪 imageLoader 的创建
inline val Context.imageLoader: ImageLoader
@JvmName("imageLoader") get() = Coil.imageLoader(this)
fun imageLoader(context: Context): ImageLoader = imageLoader ?: newImageLoader(context)
val newImageLoader = imageLoaderFactory?.newImageLoader()
?: (context.applicationContext as? ImageLoaderFactory)?.newImageLoader()
?: ImageLoader(context)
operator fun invoke(context: Context) = Builder(context).build()
fun build(): ImageLoader {
val memoryCache = memoryCache ?: buildDefaultMemoryCache()
return RealImageLoader(
context = applicationContext,
defaults = defaults,
bitmapPool = memoryCache.bitmapPool,
memoryCache = memoryCache,
//这就是创建okhttp的地方
callFactory = callFactory ?: buildDefaultCallFactory(),
eventListenerFactory = eventListenerFactory ?: EventListener.Factory.NONE,
componentRegistry = componentRegistry ?: ComponentRegistry(),
options = options,
logger = logger
)
}
OKHTTP创建
看代码很明显,我们就找到了配置缓存的地方。
private fun buildDefaultCallFactory() = lazyCallFactory {
OkHttpClient.Builder()
.cache(CoilUtils.createDefaultCache(applicationContext))
.build()
}
默认的缓存大小和目录都在这里。
fun createDefaultCache(context: Context): Cache {
val cacheDirectory = Utils.getDefaultCacheDirectory(context)
val cacheSize = Utils.calculateDiskCacheSize(cacheDirectory)
return Cache(cacheDirectory, cacheSize)
}
缓存目录
private const val CACHE_DIRECTORY_NAME = "image_cache"
fun getDefaultCacheDirectory(context: Context): File {
return File(context.cacheDir, CACHE_DIRECTORY_NAME).apply { mkdirs() }
}
缓存大小,看注释发现这个地方还借鉴了 Picasso
private const val DISK_CACHE_PERCENTAGE = 0.02
private const val MIN_DISK_CACHE_SIZE_BYTES = 10L * 1024 * 1024 // 10MB
private const val MAX_DISK_CACHE_SIZE_BYTES = 250L * 1024 * 1024 // 250MB
/** Modified from Picasso. */
fun calculateDiskCacheSize(cacheDirectory: File): Long {
return try {
val cacheDir = StatFs(cacheDirectory.absolutePath)
val size = DISK_CACHE_PERCENTAGE * cacheDir.blockCountCompat * cacheDir.blockSizeCompat
return size.toLong().coerceIn(MIN_DISK_CACHE_SIZE_BYTES, MAX_DISK_CACHE_SIZE_BYTES)
} catch (_: Exception) {
MIN_DISK_CACHE_SIZE_BYTES
}
}
计算存储大小,用总大小的百分之2来当作缓存的大小,加了一层判断,如果<10,就是10,如果>250,就还是250.
具体到 okhttp 里面还是LRU,所以这个磁盘缓存,也是会有被清掉的情况。