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

Jetpack Compose中用AndroidView嵌入自定义View出现内存泄漏如何解决

AndroidView嵌入自定义View无法回收问题解决方案

排查方向&解决方案

1. 导航配置问题

使用Navigation Compose实现底部导航时,如果配置了saveState = true的状态保存逻辑,Navigation框架会默认保存旧目的地的Composable节点和关联的View实例用于状态恢复,不会主动销毁这部分实例,属于预期行为。如果不需要状态保存,可以在导航调用的popUpTo方法中关闭saveState参数,同时导航时不设置restoreState = true,即可让旧页面退出Composition时自动释放关联资源。

2. Compose版本已知Bug

低于1.3.0版本的Compose UI存在AndroidView引用未正确释放的已知问题,当Composable节点退出Composition时,AndroidView持有的View实例可能被Compose的渲染节点树意外持有导致无法回收,升级Compose UI版本到1.3.0及以上即可解决该问题。

3. 自定义View隐式持有引用

即便当前的自定义View只有基础的文本设置逻辑,如果后续在自定义View中添加了点击监听、广播注册、RxJava/Flow订阅、全局静态类引用等逻辑,没有在onDetachedFromWindow回调中做解绑、取消订阅操作,也会导致自定义View被长期持有无法回收。可以重写MyCustomView的onDetachedFromWindow方法,在该方法中完成所有资源释放操作:

override fun onDetachedFromWindow() {
    super.onDetachedFromWindow()
    // 此处添加解绑监听器、取消订阅、清空引用等操作
}

4. 内存分析操作误差

在Android Studio中抓取内存快照前,需要手动点击Profiler中的Force Garbage Collection按钮触发多次GC,否则会存在大量还没被系统回收的临时对象被误判为内存泄漏。

临时修复方案

如果需要强制让AndroidView在页面退出时释放引用,可以给AndroidView添加唯一key参数,或者在页面的DisposableEffect回调中手动清理引用:

@Composable
fun ScreenTwo() {
    Box(modifier = Modifier.fillMaxSize()) {
        AndroidView(
            modifier = Modifier.fillMaxSize(),
            factory = { context ->
                MyCustomView(context)
            },
        )
    }
    DisposableEffect(Unit) {
        onDispose {
            // 若有外部持有MyCustomView的引用,可在此处手动置空
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:36:05