前言
如何快速高效的掌握一门学问,建议先阅读下这篇文章关于学习的一些看法。
一、概述
ViewModel 类是一种业务或页面逻辑的状态容器。用于将状态公开给界面,以及封装相关的业务逻辑。 其主要优势是可以缓存状态,并可在配置更改后(例如旋转屏幕时)持久保留相应状态。
二、设计目的
数据持久化:ViewModel设计的主要目的是解决Activity/Fragment因配置变更(如屏幕旋转)导致的重建过程中数据丢失的问题。它提供了一个持久化的数据容器,即使UI组件重建,ViewModel也能保持其数据状态。UI与数据分离:ViewModel实现了UI与页面/业务逻辑的解耦。它负责管理与UI相关的数据,而UI则专注于数据的呈现与用户交互。
三、生命周期感知
关联生命周期:ViewModel与特定的Activity/Fragment生命周期相关联,但其生命周期比它们更长。当Activity/Fragment进入后台或销毁时,ViewModel不会立即被销毁,只有当与其关联的所有UI组件都被销毁且系统资源紧张时,ViewModel才会被清理。onCleared()回调:当ViewModel即将被清理时,系统会调用其onCleared()方法,开发者可以在此处释放资源,如关闭网络连接、取消订阅等。
四、实现原理
ViewModelProvider:创建ViewModel实例通常通过ViewModelProvider类实现,它需要一个ViewModelStoreOwner(如Activity或Fragment)和一个可选的ViewModelProvider.Factory。ViewModelProvider会根据传入的类名或键(通常为类名)在ViewModelStore中查找或创建ViewModel实例。ViewModelStore:ViewModelStore是一个简单的键值对集合,用于存储与特定ViewModelStoreOwner关联的ViewModel实例。当ViewModelStoreOwner(如Activity)被销毁时,其关联的ViewModelStore也会被清理,进而导致所有ViewModel实例被清除。ViewModelStoreOwner:这是一个接口,Activity和Fragment都实现了该接口,意味着它们都可以拥有自己的ViewModelStore。这使得每个UI组件都能独立管理自己的ViewModel集。
五、内存管理
弱引用:ViewModel对ViewModelStoreOwner(如Activity)持有的是弱引用,避免了内存泄漏。当Activity被销毁时,尽管ViewModel还在内存中,但由于弱引用已被清除,系统在适当的时候可以安全回收ViewModel。ViewModel.onCleared():当ViewModel不再被任何UI组件引用且即将被系统回收时,会触发onCleared()方法。开发者应在其中释放所有与ViewModel关联的资源,如关闭数据库连接、取消网络请求等。
六、协程支持
ViewModelScope:Android Jetpack提供了ViewModelScope,这是一个与ViewModel生命周期绑定的CoroutineScope。在ViewModel中使用viewModelScope.launch {...}启动的协程,会在ViewModel被清除时自动取消,确保资源释放。
七、最佳实践
避免持有UI引用:ViewModel不应直接持有Activity/Fragment或View的引用,以防引起内存泄漏。。结合LiveData使用:与LiveData结合使用,可以确保数据在正确的时间(如Activity/Fragment处于活跃状态)安全地传递给UI,同时避免内存泄漏和数据竞争。使用AndroidViewModel:对于需要访问Application上下文的ViewModel,可以继承自AndroidViewModel,它提供了对Application对象的直接访问。
码字不易,记得关注+点赞+收藏