ViewModel在Activity和Fragment之间共享

在 Android 的 Jetpack ViewModel 架构组件中:

  • Activity 中使用 by viewModels() 创建的 ViewModel,默认作用域是该 Activity
  • Fragment 中使用 by activityViewModels() 创建的 ViewModel,其作用域也是 宿主 Activity

因此,只要 ViewModel 的类型相同,并且使用的是默认的 Factory 和 key(即没有自定义 key),那么无论你是在 Activity 中通过 viewModels() 还是在 Fragment 中通过 activityViewModels() 获取,它们都会共享同一个 ViewModel 实例

原理简述

ViewModel 是通过 ViewModelStoreOwner 来管理生命周期和存储的。

  • Activity 是一个 ViewModelStoreOwner
  • viewModels() 在 Activity 中会从 Activity 自己的 ViewModelStore 中获取或创建 ViewModel。
  • activityViewModels() 在 Fragment 中会委托到其宿主 Activity 的 ViewModelStore 中去获取或创建 ViewModel。

所以,两者访问的是同一个 ViewModelStore,对于同一个 ViewModel 类型,会返回同一个实例。

示例代码

1
2
3
4
5
6
7
8
9
// Activity
class MainActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
}

// Fragment
class MyFragment : Fragment() {
private val viewModel: MyViewModel by activityViewModels()
}

在这个例子中,MainActivity.viewModelMyFragment.viewModel 指向的是同一个对象实例

注意事项

  • 如果你在 viewModels()activityViewModels() 中传入了不同的 factory 或自定义的 key 参数,那么可能会创建不同的实例。
  • 确保 ViewModel 的构造方式一致(比如都使用默认构造或相同的 ViewModelProvider.Factory)。

总结

是同一个 ViewModel 实例,不会重复创建,前提是:

  • ViewModel 类型相同;
  • 使用默认或相同的 factory;
  • 没有指定不同的 key。

这是 ViewModel 实现 Activity 与 Fragment 之间共享数据 的核心机制之一。