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

全局单例NavHostController是否合理?内存泄漏问题及修正方案

为什么会出现内存泄漏?
  • NavHostController内部持有关联组件(比如Activity)的Context实例,而你创建的NavControllerDelegate是静态单例——它的生命周期和整个应用进程绑定,永远不会被GC回收。
  • 当Activity被销毁时,系统本应回收Activity及其Context,但单例还强握着NavHostController的引用,导致Activity的Context无法被垃圾回收器清理,最终造成内存泄漏。
  • Android Lint的警告就是专门检测这种“静态字段持有Context类实例”的高危场景。
安全的修改方案

核心思路是避免强引用长期持有NavHostController,同时在组件销毁时主动切断引用:

1. 改用弱引用包裹

把单例里的强引用换成WeakReference,这样GC可以在需要时自动回收NavHostController实例:

object NavControllerDelegate {
    private var _navController: WeakReference<NavHostController>? = null

    var navController: NavHostController?
        get() = _navController?.get()
        set(value) {
            _navController = value?.let { WeakReference(it) }
        }
}

2. 在组件销毁时主动清空引用

仅靠弱引用还不够稳妥,最好在Activity销毁时主动清空单例的引用,彻底切断关联:
在承载Compose的Activity中重写onDestroy方法:

override fun onDestroy() {
    super.onDestroy()
    NavControllerDelegate.navController = null
}

注意事项

  • 访问NavControllerDelegate.navController时一定要判空,因为弱引用的对象可能已经被GC回收。
  • 如果在ViewModel中使用,建议结合viewModelScope的生命周期,避免ViewModel销毁后还持有无效引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:44:54