viewmodel
CreationExtras
ViewModel创建过程中传递额外参数的容器。InitializerViewModelFactory
ViewModelProvider.Factory接口实现类,使用ViewModelInitializer来创建ViewModel实例。
InitializerViewModelFactoryBuilder
用于构建InitializerViewModelFactory的工具,通常以DSL形式提供。
MutableCreationExtras
可变版本的CreationExtras,允许添加或修改额外参数。
ViewModelFactoryDsl
一个DSL(领域特定语言),用于更声明式地定义如何创建ViewModel。
ViewModelInitializer
用于初始化ViewModel的类,通常与ViewModelFactoryDsl一起使用。
InitializerViewModelFactory
提供了使用InitializerViewModelFactory的Kotlin扩展。
AndroidViewModel
AndroidViewModel是ViewModel的一个子类,它接受应用程序的Application作为上下文,这对于需要访问Application资源的ViewModel特别有用。
HasDefaultViewModelProviderFactory
一个接口,标识一个类拥有默认的ViewModelProvider.Factory,用于创建ViewModel。
ViewModel
ViewModelLazy
一个提供懒加载ViewModel实例的工具类。
ViewModelProvider
用于获取ViewModel实例,确保配置更改时ViewModel可以持续使用。
ViewModelStore
用于保存ViewModel实例的类,以便它们可以跨配置更改持续存在。
ViewModelStoreOwner
一个接口,标识一个类可以拥有ViewModelStore。
ViewTreeViewModelStoreOwner
用于从视图树中查找ViewModelStoreOwner的工具类。
ViewTreeViewModelKt
提供了操作和查询视图树中ViewModel的Kotlin扩展
ViewModelStore
1 | package androidx.lifecycle; |
如果有不想保存的数据可以在存储前调用 ViewModelStore clear 函数
使用场景
Activity或Fragment销毁时
在Activity或Fragment的onDestroy
方法中调用ViewModelStore
的clear
方法,可以确保所有关联的ViewModel
能够及时清理资源。这是因为,在某些情况下(如用户明确退出Activity或Fragment),保留ViewModel不再有意义,应该清除所有资源以避免内存泄漏。
示例代码:
1 | javaCopy code |
这里,isFinishing()
用于检查Activity是否正在结束(用户退出或因其他原因被销毁),如果是,则清理ViewModelStore中的所有ViewModel。
在使用ViewModel时实现资源管理
如果你的应用程序具有复杂的业务逻辑,可能会创建多个ViewModel用于不同的数据处理和业务逻辑。在这种情况下,当确定某些ViewModel不再需要时,可以通过调用clear
方法释放这些ViewModel占用的资源。
3. 单元测试
在进行单元测试时,特别是在测试涉及ViewModel生命周期的逻辑时,clear
方法可以在测试完成后被调用来清理测试环境,保证每个测试运行的隔离性。
注意事项:
虽然clear
方法的使用可以帮助管理资源,但需要谨慎使用,以避免在不适当的时机释放资源导致的应用崩溃或不稳定。通常,Android框架会自动处理ViewModel的生命周期,只有在特定情况下,如Activity或Fragment被销毁时,才需要手动调用clear
方法。
ViewModelStoreOwner
1 | package androidx.lifecycle; |
我们来看一下到底谁是 ViewModelStoreOwner
ViewModelStoreOwner - ComponentActivity
1 |
|
ViewModelStoreOwner - Fragment
1 |
|
ViewTreeViewModelStoreOwner
1 | package androidx.lifecycle; |
ViewTreeViewModelStoreOwner 与 ViewModelStoreOwner 有什么区别
ViewModelStoreOwner
- 定义:
ViewModelStoreOwner
是一个接口,定义了可以拥有并管理ViewModelStore
的类。ViewModelStore
是一个容器,用于存储和管理ViewModel
实例,确保它们能够跨配置更改(如屏幕旋转)生存下来。 - 用途:这个接口通常由Activity和Fragment实现,使它们能够持有
ViewModel
实例。通过这种方式,Activity或Fragment可以在内部管理其ViewModels
的生命周期,确保在发生配置更改时,ViewModels
不会被销毁并重新创建。 - 实现方式:在使用
ViewModel
时,开发者通常不需要直接实现ViewModelStoreOwner
接口。例如,AppCompatActivity
和Fragment
已经实现了这个接口,提供了对ViewModelStore
的访问。
ViewTreeViewModelStoreOwner
- 定义:
ViewTreeViewModelStoreOwner
是与Android视图树(View Tree)相关的工具类。它提供了静态方法来从视图树中查找ViewModelStoreOwner
。这是通过在视图的Tag
中设置和获取ViewModelStoreOwner
实现的。 - 用途:
ViewTreeViewModelStoreOwner
的主要用途是在视图层级中找到最近的ViewModelStoreOwner
。这对于自定义视图或视图组件特别有用,这些组件需要访问ViewModel
但不直接与Activity或Fragment关联。 - 使用场景:当你有一个嵌套在深层视图层次结构中的自定义视图,并且这个视图需要访问
ViewModel
时,可以使用ViewTreeViewModelStoreOwner.get(view)
来找到最近的ViewModelStoreOwner
实例。这使得即使在复杂的视图结构中,自定义视图也能正确地管理和访问ViewModel
实例。
区别
- 作用范围:
ViewModelStoreOwner
直接关联于可以持有ViewModelStore
的实体(如Activity或Fragment),而ViewTreeViewModelStoreOwner
是一个工具类,用于在视图树中查找这些实体。 - 使用上下文:
ViewModelStoreOwner
通常用于直接管理ViewModels
的生命周期,特别是在Activity和Fragment中。ViewTreeViewModelStoreOwner
则用于在视图层级中寻找ViewModelStoreOwner
,便于自定义视图或组件访问ViewModels
。 - 实现与调用:Activity和Fragment通常自动实现
ViewModelStoreOwner
接口。相反,ViewTreeViewModelStoreOwner
提供了一种机制,允许在视图树中任意位置将视图与最近的ViewModelStoreOwner
关联起来,而无需直接实现或管理ViewModelStoreOwner
接口。
简而言之,ViewModelStoreOwner
关注于拥有和管理ViewModelStore
的能力,而ViewTreeViewModelStoreOwner
提供了一种查找视图树中最近的ViewModelStoreOwner
的方法,使得在复杂的视图结构中的组件也能访问和使用ViewModels
。
ViewModelStoreOwner 的 set 方法
ViewModelStoreOwner 的 set 方法是什么时候被调用的,被添加到哪个 View 的 Tag 中?
androidx.activity.ComponentActivity 中的调用时机
androidx.activity.ComponentActivity#setContentView(android.view.View)
1 |
|
androidx.activity.ComponentActivity#addContentView
1 |
|
在 initViewTreeOwners 中调用 ViewModelStoreOwner 的 set
androidx.activity.ComponentActivity#initViewTreeOwners
1 | private void initViewTreeOwners() { |
这里顺便提一下 ViewTreeLifecycleOwner,ViewTreeSavedStateRegistryOwner,ViewTreeOnBackPressedDispatcherOwner
在Android Jetpack架构组件中,ViewTreeLifecycleOwner
、ViewTreeSavedStateRegistryOwner
和ViewTreeOnBackPressedDispatcherOwner
是用于在视图树中传递和存储与生命周期、状态保存和返回按钮事件处理相关的对象的工具类。它们允许开发者在任何视图层级中访问与这些功能相关的对象,增强了组件化和模块化开发的灵活性。
ViewTreeLifecycleOwner
ViewTreeLifecycleOwner
与LifecycleOwner
接口相关,后者是一个类可以实现的接口,表示这个类有一个生命周期,比如Activity或Fragment。ViewTreeLifecycleOwner
提供了静态方法来在视图树中设置和获取LifecycleOwner
。这使得在视图树中的任何位置,都可以访问到与之相关联的LifecycleOwner
,进而可以根据生命周期事件来管理资源,比如开始/停止数据加载、绑定/解绑资源等。
ViewTreeSavedStateRegistryOwner
ViewTreeSavedStateRegistryOwner
与SavedStateRegistryOwner
接口相关,后者管理和存储状态,以便在进程被杀后恢复状态。通过ViewTreeSavedStateRegistryOwner
,开发者可以为视图树中的任何视图设置和获取与状态保存相关的SavedStateRegistryOwner
。这使得即使是自定义视图也能够利用Android的状态保存机制,无需依赖于Activity或Fragment来保存和恢复状态。
ViewTreeOnBackPressedDispatcherOwner
ViewTreeOnBackPressedDispatcherOwner
与OnBackPressedDispatcherOwner
接口相关,后者提供了一个组件化的方式来处理返回按钮事件。ViewTreeOnBackPressedDispatcherOwner
允许开发者为视图树中的任何视图设置和获取OnBackPressedDispatcherOwner
。这意味着在任何视图中,都可以独立处理返回按钮的点击事件,而不是仅限于在Activity中处理。这对于构建复杂的用户界面和处理嵌套的用户交互特别有用。
使用场景和好处
- 组件化开发:这些工具类支持更加组件化的开发方式,视图或组件可以独立于Activity或Fragment使用这些架构组件。
- 灵活性和可重用性:使得自定义视图和组件更加灵活,易于重用,因为它们可以在不依赖特定Activity或Fragment的情况下,管理自己的生命周期、状态保存和返回按钮处理。
- 简化代码:简化了在自定义视图或深层嵌套的视图结构中访问这些功能的方式,避免了复杂的回调结构或过度依赖于上下文。
综上所述,ViewTreeLifecycleOwner
、ViewTreeSavedStateRegistryOwner
和ViewTreeOnBackPressedDispatcherOwner
为Android开发者提供了强大的工具,以更加灵活和模块化的方式处理生命周期管理、状态保存和返回按钮事件处理。
ViewTreeViewModelKt
Google 也准备了一个 Kotlin 使用的扩展函数配合 ViewModelStoreOwner
1 | package androidx.lifecycle |