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

KMP中使用Koin时ViewModel返回后未销毁问题求助

解决KMP中Koin ViewModel重复实例问题

问题原因

默认情况下,koinViewModel会绑定到当前的生命周期Scope(如导航条目或组件Scope),页面返回后该Scope未被销毁,导致再次进入时复用旧ViewModel实例。直接使用时间戳作为key无效,因为Scope本身未更新,Koin仍会在同一个Scope中查找对应key的实例。

解决方案

通过创建页面专属的临时Scope,绑定ViewModel到该Scope,页面销毁时关闭Scope,确保ViewModel被回收,每次进入页面都生成新实例。

步骤1:正确声明ViewModel

在Koin模块中,使用viewModel声明(保证ViewModel的生命周期管理):

val appModule = module {
    viewModel { AddOrEditViewModel(get()) }
    // 其他依赖声明...
}

步骤2:在Compose页面中使用临时Scope

@Composable
fun AddOrEditScreen() {
    // 每次进入页面创建新的专属Scope
    val screenScope = remember { getKoin().createScope() }
    
    // 页面销毁时关闭Scope,触发ViewModel销毁
    DisposableEffect(screenScope) {
        onDispose {
            screenScope.close()
        }
    }
    
    // 从临时Scope获取ViewModel,确保每次都是新实例
    val viewModel = koinViewModel<AddOrEditViewModel>(scope = screenScope)
    
    // 页面UI逻辑...
}

替代方案:使用Factory声明(无生命周期管理)

如果不需要ViewModel的跨配置变更保留,可将ViewModel声明为factory,每次调用get()获取新实例:

// Koin模块声明
val appModule = module {
    factory { AddOrEditViewModel(get()) }
}

// Compose页面中获取
val viewModel = remember { getKoin().get<AddOrEditViewModel>() }

注意:此方式下ViewModel不会自动跟随页面生命周期销毁,需手动管理实例。

关键说明

  • 使用临时Scope的方式既保留了ViewModel的生命周期管理,又能确保每次进入页面生成新实例。
  • 避免直接使用时间戳作为key,因为Scope未更新时,Koin仍会在同一Scope中复用实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:24:51