You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中如何正确回收Bitmap以避免内存溢出?

问题原因

你遇到的错误是因为手动回收Bitmap的时机和Compose组件生命周期、Lazy列表复用机制冲突:

  • 你把DisposableEffect的key设为Image组件,这会导致重组时频繁触发回收逻辑,而此时Image可能还在引用该Bitmap;
  • LazyVerticalGrid的item会被放入复用池,当item被复用绑定新数据时,旧的Bitmap已经被回收,但如果复用的item还持有旧Bitmap的引用,就会触发"使用已回收Bitmap"的错误。
正确解决方案

方案一:使用图片加载库(推荐)

不要手动管理Bitmap,直接用Coil、Glide这类适配Compose的图片加载库,它们会自动处理缓存、内存复用和Bitmap回收,完全避免手动回收的问题。

以Coil为例,改造代码:

@Composable
fun ComicCoverView(comic: ComicCover, onComicClicked: (ComicCover) -> Unit) {
    Card {
        AsyncImage(
            modifier = Modifier
                .height(180.dp)
                .clickable { onComicClicked(comic) },
            model = comic.cover, // 直接传Bitmap/图片路径/Uri,Coil自动处理
            contentDescription = null,
            contentScale = ContentScale.FillHeight,
        )
    }
}

Coil会自动维护Bitmap的生命周期,当组件被销毁或移出可视区域时,自动回收闲置的Bitmap,无需手动调用recycle()。

方案二:手动管理Bitmap(仅特殊场景使用)

如果必须手动管理,需要调整DisposableEffect的触发时机,确保只有当ComicCover实例切换时才回收旧Bitmap,并且保证回收时Bitmap不再被引用:

@Composable
fun ComicCoverView(comic: ComicCover, onComicClicked: (ComicCover) -> Unit) {
    Card {
        val currentBitmap = remember(comic.id) { comic.cover.asImageBitmap() }
        
        DisposableEffect(comic.id) {
            onDispose {
                // 仅当ComicCover的id变化时,回收旧的Bitmap
                if (!currentBitmap.isRecycled) {
                    currentBitmap.recycle()
                }
            }
        }

        Image(
            modifier = Modifier
                .height(180.dp)
                .clickable { onComicClicked(comic) },
            bitmap = currentBitmap,
            contentDescription = null,
            contentScale = ContentScale.FillHeight,
        )
    }
}
  • 用remember(comic.id)缓存Bitmap,确保同一个ComicCover的Bitmap不会重复创建;
  • DisposableEffect的key设为comic.id,只有当item绑定的ComicCover变化时,才回收旧的Bitmap;
  • 回收前先判断isRecycled,避免重复回收。

注意:手动管理Bitmap很容易踩生命周期的坑,除非特殊需求,优先用图片加载库。

内容的提问来源于stack exchange,提问作者Benjamin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:05:26