首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Kotlin AsyncImage线圈没有正确地缓存图像,每次都在重新加载

Kotlin AsyncImage线圈没有正确地缓存图像,每次都在重新加载
EN

Stack Overflow用户
提问于 2022-08-03 11:33:24
回答 1查看 727关注 0票数 2

我正在使用线圈依赖项,所以我可以利用AsyncImage

我就是这样展示我的图像的:

代码语言:javascript
运行
复制
    AsyncImage(
        model = ImageRequest.Builder(LocalContext.current)
            .data(img)
            .crossfade(true)
            .memoryCachePolicy(
                CachePolicy.ENABLED)
            .build(),
        placeholder = painterResource(R.drawable.default_profile_picture),
        contentDescription = "Profile Picture",
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .clip(RoundedCornerShape(100.dp))
            .size(100.dp)
    )

我遇到的问题是缓存。我期望每下载一张图片,它就会被缓存,在应用程序打开时,它就会简单地出现!

然而,每次启动应用程序时,我都会看到占位符,然后再下载图像。我打错AsyncImage了吗?

更新

我更新了如何在imageLoader ()类中使用imageLoaderi来实现imageLoader,上下文为applicationContext

代码语言:javascript
运行
复制
override fun newImageLoader(): ImageLoader = ImageLoader.Builder(applicationContext)
        .diskCache {
            DiskCache.Builder()
                .directory(applicationContext.cacheDir.resolve("image_cache"))
                .maxSizePercent(0.25)
                .build()
        }
        .networkCachePolicy(CachePolicy.ENABLED)
        .diskCachePolicy(CachePolicy.ENABLED)
        .respectCacheHeaders(false)
        .addLastModifiedToFileCacheKey(true)
        .build()

这是我的@Composable

代码语言:javascript
运行
复制
         val request: ImageRequest = ImageRequest.Builder(LocalContext.current.applicationContext)
                .data(profile.value?.img)
                .crossfade(true)
                .diskCacheKey(profile.value?.img)
                .build()

            LocalContext.current.applicationContext.imageLoader.enqueue(request)

            AsyncImage(
                model = request,
                placeholder = painterResource(R.drawable.default_profile_picture),
                contentDescription = "Profile Picture",
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .clip(RoundedCornerShape(100.dp))
                    .size(50.dp)
            )

但是,这些图像似乎需要更长的时间才能加载?我甚至添加了我希望它们保存在的确切的diskCacheKey。

有人能告诉我我在哪里做错了什么吗?

更新2

这是我更新的ImageLoader

代码语言:javascript
运行
复制
 override fun newImageLoader(): ImageLoader = ImageLoader.Builder(applicationContext)
        .diskCache {
            DiskCache.Builder()
                .directory(applicationContext.cacheDir.resolve("image_cache"))
                .maxSizePercent(0.25)
                .build()
        }
        .networkCachePolicy(CachePolicy.ENABLED)
        .diskCachePolicy(CachePolicy.ENABLED)
        .respectCacheHeaders(true)
        .build()

我就是这样展示图像的:

代码语言:javascript
运行
复制
val request: ImageRequest = ImageRequest.Builder(LocalContext.current.applicationContext)
   .data(space.img)
   .crossfade(true)
   .diskCacheKey(space.img)
   .diskCachePolicy(CachePolicy.ENABLED)
   .setHeader("Cache-Control", "max-age=31536000")
   .build()


AsyncImage(
   model = request,
   placeholder = painterResource(R.drawable.default_space_picture),
   contentDescription = "Space Picture",
   contentScale = ContentScale.Crop,
   modifier = Modifier
       .clip(RoundedCornerShape(100.dp))
       .size(50.dp)
)

当我试图做的时候:

代码语言:javascript
运行
复制
SubcomposeAsyncImage(
    model = request,
    contentDescription = "Profile Picture",
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .clip(RoundedCornerShape(100.dp))
        .size(50.dp)
) {
    val state = painter.state
    if (state is AsyncImagePainter.State.Success) {
        SubcomposeAsyncImageContent()
        LaunchedEffect(Unit) {
            Log.d("DATASOURCE", state.result.dataSource.toString())
            println(context.imageLoader.diskCache?.get(space.img)?.data)
        }
    }
}

我明白了:

代码语言:javascript
运行
复制
2022-08-06 14:02:30.928 5225-5225/com.app.app D/DATASOURCE: NETWORK
2022-08-06 14:02:30.929 5225-5225/com.app.app I/System.out: /data/user/0/com.billbandits.hero/cache/image_cache/746b90d410c17e9d5a5d705a69e69d45afe12b20b8f234972e7394a6052e8033.1

所以我现在的问题是,怎么会有一个磁盘缓存键,它仍然在请求来自Network的映像

EN

Stack Overflow用户

发布于 2022-08-04 00:49:35

您需要磁盘缓存而不是内存缓存。但在默认情况下,两者都是启用的。

问题是,默认情况下,线圈根据缓存控制http报头字段决定是否要磁盘缓存。如果您需要忽略缓存控制,可以将respectCacheHeaders设置为ImageLoader

代码语言:javascript
运行
复制
        /**
         * Enables support for network cache headers. If enabled, this image loader will respect the
         * cache headers returned by network responses when deciding if an image can be stored or
         * served from the disk cache. If disabled, images will always be served from the disk cache
         * (if present) and will only be evicted to stay under the maximum size.
         *
         * Default: true
         */
        fun respectCacheHeaders(enable: Boolean) = apply {
            this.options = this.options.copy(respectCacheHeaders = enable)
        }

若要检查用于此映像的数据源,可以使用SubcomposeAsyncImage。例如:

代码语言:javascript
运行
复制
SubcomposeAsyncImage(
    model = request,
    contentDescription = "Profile Picture",
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .clip(RoundedCornerShape(100.dp))
        .size(50.dp)
) {
    val state = painter.state
    if (state is AsyncImagePainter.State.Success) {
        SubcomposeAsyncImageContent()
        LaunchedEffect(Unit) { println(state.result.dataSource) }
    }
}
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73221013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档