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

如何通过Koin注入带ViewModel回调的对象并实现ViewModel单例?

解决Koin注入带ViewModel回调对象的问题

你遇到的核心问题是:Koin的viewModel{}是和组件(Activity/Fragment)的Scope绑定的工厂模式,直接在注入BarcodeDataReceiver时调用get<MyViewModel>(),会因为没有关联当前组件的Scope而创建新实例,无法拿到你需要的那个ViewModel。下面是两种可行的解决方案:

方案一:在组件Scope内绑定并传递ViewModel实例

利用Koin的scoped绑定,让BarcodeDataReceiver和ViewModel共享当前组件的Scope,确保引用的是同一个ViewModel实例:

  1. 先在Koin模块中定义绑定,接收ViewModel作为参数:
module {
    viewModel { MyViewModel(get()) }
    scoped { (viewModel: MyViewModel) ->
        BarcodeDataReceiver { viewModel.addItem(it) }
    }
}
  1. 在你的Activity/Fragment中,先获取ViewModel,再通过组件Scope注入BarcodeDataReceiver:
private val viewModel: MyViewModel by viewModel()
private val barcodeDataReceiver: BarcodeDataReceiver by inject { parametersOf(viewModel) }

方案二:用Factory绑定传递ViewModel实例

如果不需要BarcodeDataReceiver复用,也可以用factory绑定,同样通过参数传递ViewModel:

  1. Koin模块定义:
module {
    viewModel { MyViewModel(get()) }
    factory { (viewModel: MyViewModel) ->
        BarcodeDataReceiver { viewModel.addItem(it) }
    }
}
  1. 组件中注入:
private val viewModel: MyViewModel by viewModel()
private val barcodeDataReceiver: BarcodeDataReceiver by inject { parametersOf(viewModel) }

为什么之前的尝试无效?

你用single{}包裹viewModel{}的思路是错误的——viewModel{}本身是绑定到组件Scope的工厂,而single{}是全局单例,两者的Scope完全不兼容,自然无法拿到当前组件的ViewModel实例。必须让BarcodeDataReceiver的注入关联到当前组件的Scope,或者显式传递ViewModel实例,才能确保引用正确。

内容的提问来源于stack exchange,提问作者Miguel Vila Ojito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:31:13