ViewModel vs AndroidViewModel:核心区别与使用场景详解

发布于:2025-04-12 ⋅ 阅读:(34) ⋅ 点赞:(0)

在 Android 的 MVVM 架构中,ViewModelAndroidViewModel 都是用于管理 UI 相关数据的组件,但二者有一些关键区别:


1. ViewModel

  • 基本用途:用于存储和管理与 UI 相关的数据,生命周期与 Activity/Fragment 解耦(即使配置变更如屏幕旋转,数据也不会丢失)。
  • 依赖关系:不直接依赖 Android 框架(如 Context)。
  • 适用场景:适合纯逻辑数据处理,不需要 Context 的情况。
  • 示例代码
    class MyViewModel : ViewModel() {
        private val _data = MutableLiveData<String>()
        val data: LiveData<String> get() = _data
        
        fun fetchData() {
            // 业务逻辑(无需 Context)
            _data.value = "Hello, ViewModel!"
        }
    }
    

2. AndroidViewModel

  • 基本用途:继承自 ViewModel,但内部持有 Application 上下文(通过 getApplication() 获取)。
  • 依赖关系:依赖 Application 上下文(注意:避免持有 ActivityContext,防止内存泄漏)。
  • 适用场景:需要访问 Android 系统资源(如数据库、SharedPreferences、资源文件等)时使用。
  • 示例代码
    class MyAndroidViewModel(application: Application) : AndroidViewModel(application) {
        private val _data = MutableLiveData<String>()
        val data: LiveData<String> get() = _data
        
        fun 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 上下文,切勿持有 ActivityView 的引用。

扩展说明

  • 如果只需要 Application 上下文,也可以通过依赖注入(如 Hilt)将 Application 注入到普通 ViewModel 中,而非继承 AndroidViewModel。这是更现代的做法:
    class MyViewModel @Inject constructor(
        private val application: Application
    ) : ViewModel() { ... }
    

根据需求选择合适的方式,保持代码的清晰和可测试性。


网站公告

今日签到

点亮在社区的每一天
去签到