如何通过Koin注入带ViewModel回调的对象并实现ViewModel单例?
解决Koin注入带ViewModel回调对象的问题
你遇到的核心问题是:Koin的viewModel{}是和组件(Activity/Fragment)的Scope绑定的工厂模式,直接在注入BarcodeDataReceiver时调用get<MyViewModel>(),会因为没有关联当前组件的Scope而创建新实例,无法拿到你需要的那个ViewModel。下面是两种可行的解决方案:
方案一:在组件Scope内绑定并传递ViewModel实例
利用Koin的scoped绑定,让BarcodeDataReceiver和ViewModel共享当前组件的Scope,确保引用的是同一个ViewModel实例:
- 先在Koin模块中定义绑定,接收ViewModel作为参数:
module { viewModel { MyViewModel(get()) } scoped { (viewModel: MyViewModel) -> BarcodeDataReceiver { viewModel.addItem(it) } } }
- 在你的Activity/Fragment中,先获取ViewModel,再通过组件Scope注入
BarcodeDataReceiver:
private val viewModel: MyViewModel by viewModel() private val barcodeDataReceiver: BarcodeDataReceiver by inject { parametersOf(viewModel) }
方案二:用Factory绑定传递ViewModel实例
如果不需要BarcodeDataReceiver复用,也可以用factory绑定,同样通过参数传递ViewModel:
- Koin模块定义:
module { viewModel { MyViewModel(get()) } factory { (viewModel: MyViewModel) -> BarcodeDataReceiver { viewModel.addItem(it) } } }
- 组件中注入:
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
相关产品推荐
相关产品推荐

