使用Koin在Java Activity与Kotlin Fragment间共享带构造参数的ViewModel
问题根源
你拿到两个不同实例的核心原因是Activity侧的获取方式没有走Jetpack ViewModel的生命周期绑定逻辑:
- Activity中用的
get()是Koin的普通依赖获取方法,默认直接从全局容器生成实例,不会将生成的ViewModel存入Activity的ViewModelStore中 - 而Fragment侧的
sharedViewModel()默认会从宿主Activity的ViewModelStore中查找ViewModel,找不到就会新建一个存入,因此两边拿到的是不同实例
解决方案
步骤1:确认ViewModel的Koin声明正确
必须用Koin的viewModel DSL声明ViewModel,不能用single或factory,只有viewModel DSL会适配Jetpack ViewModel的生命周期存储逻辑:
val appModule = module { // 示例:构造参数需要SavedStateRegistryOwner(比如Activity/Fragment实例)和其他依赖 viewModel { (owner: SavedStateRegistryOwner) -> MyViewModel(owner, get<YourOtherDependency>()) } }
步骤2:修改Activity侧的ViewModel获取方式
Java中不要直接用get()获取ViewModel,改用Koin适配Jetpack生命周期的获取API:
// 导入需要的类 // import org.koin.androidx.viewmodel.ViewModelLifecycleOwnerKt; // import org.koin.core.parameter.ParametersHolderKt; MyViewModel viewModel = ViewModelLifecycleOwnerKt.getViewModel( this, MyViewModel.class, // 明确指定ViewModel的类 null, // 无限定符可传null owner -> ParametersHolderKt.parametersOf(this) );
核心是要让ViewModel存入当前Activity的ViewModelStore。
步骤3:对齐Fragment侧的传参
如果你的ViewModel构造需要传入参数,要保证Fragment侧sharedViewModel()传入的参数和Activity侧一致:
private val viewModel: MyViewModel by sharedViewModel { parametersOf(requireActivity()) }
如果不需要额外传参,保持原来的写法即可。
验证
运行后分别打印Activity和Fragment获取到的ViewModel的hashCode(),确认一致即代表共享成功。
内容的提问来源于stack exchange,提问作者abhishek maharajpet
相关产品推荐
相关产品推荐

