Coil 1.4 版本的磁盘缓存大小

339 阅读1分钟

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,所以这个磁盘缓存,也是会有被清掉的情况。