在 Android 的 MVVM 架构中,ViewModel 和 AndroidViewModel 都是用于管理 UI 相关数据的组件,但二者有一些关键区别:
1. ViewModel
- 基本用途:用于存储和管理与 UI 相关的数据,生命周期与
Activity/Fragment解耦(即使配置变更如屏幕旋转,数据也不会丢失)。 - 依赖关系:不直接依赖 Android 框架(如
Context)。 - 适用场景:适合纯逻辑数据处理,不需要
Context的情况。 - 示例代码:
class MyViewModel : ViewModel() {private val _data = MutableLiveData<String>()val data: LiveData<String> get() = _datafun fetchData() {// 业务逻辑(无需 Context)_data.value = "Hello, ViewModel!"} }
2. AndroidViewModel
- 基本用途:继承自
ViewModel,但内部持有Application上下文(通过getApplication()获取)。 - 依赖关系:依赖
Application上下文(注意:避免持有Activity的Context,防止内存泄漏)。 - 适用场景:需要访问 Android 系统资源(如数据库、SharedPreferences、资源文件等)时使用。
- 示例代码:
class MyAndroidViewModel(application: Application) : AndroidViewModel(application) {private val _data = MutableLiveData<String>()val data: LiveData<String> get() = _datafun fetchData() {// 使用 Application 上下文(如访问资源或数据库)val appName = getApplication<Application>().resources.getString(R.string.app_name)_data.value = "Data from ${appName}"} }
关键区别总结
| 特性 | ViewModel | AndroidViewModel |
|---|---|---|
| 父类 | androidx.lifecycle.ViewModel | ViewModel 的子类 |
| Context 支持 | 无 | 提供 Application 上下文 |
| 使用场景 | 纯逻辑处理 | 需要访问 Android 系统资源(如数据库) |
| 内存泄漏风险 | 无 | 低(仅持有 Application Context) |
如何选择?
- 优先用
ViewModel:除非需要Context,否则尽量用ViewModel,避免不必要的上下文依赖。 - 谨慎使用
Context:即使使用AndroidViewModel,也只用Application上下文,切勿持有Activity或View的引用。
扩展说明
- 如果只需要
Application上下文,也可以通过依赖注入(如 Hilt)将Application注入到普通ViewModel中,而非继承AndroidViewModel。这是更现代的做法:class MyViewModel @Inject constructor(private val application: Application ) : ViewModel() { ... }
根据需求选择合适的方式,保持代码的清晰和可测试性。