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 |