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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:48:04