在 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() { ... }
根据需求选择合适的方式,保持代码的清晰和可测试性。