You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVVM模式下多ViewModel共享Model的正确初始化方式问询

无依赖注入框架下的多ViewModel共享Model方案

针对你遇到的问题,这里提供一种完全符合MVVM原则(View不感知Model)且无需依赖注入框架的实现方式:通过共享ViewModel持有Model,让多个业务ViewModel从共享ViewModel中获取同一Model实例。

实现步骤

1. 定义Model类

Model负责业务逻辑和数据存储,内部通过LiveData对外暴露状态:

class ClickHandler {
    private val _displayText = MutableLiveData<String>().apply {
        value = "初始文本"
    }
    val displayText: LiveData<String> = _displayText

    fun handleButtonClick() {
        _displayText.value = "按钮已点击,文本更新"
    }
}

2. 创建共享ViewModel

这个ViewModel唯一职责是持有Model实例,作为多个业务ViewModel的共享依赖:

class SharedStateViewModel : ViewModel() {
    // 初始化共享的Model实例
    val clickHandler = ClickHandler()
}

3. 实现业务ViewModel

ButtonViewModel和TextViewModel通过构造参数接收共享ViewModel,进而获取同一Model实例:

// ButtonViewModel:处理按钮点击逻辑
class ButtonViewModel(private val sharedState: SharedStateViewModel) : ViewModel() {
    fun onButtonClicked() {
        sharedState.clickHandler.handleButtonClick()
    }
}

// TextViewModel:对外暴露要展示的文本LiveData
class TextViewModel(private val sharedState: SharedStateViewModel) : ViewModel() {
    val showText: LiveData<String> = sharedState.clickHandler.displayText
}

4. Activity中初始化ViewModel

View层仅与ViewModel交互,完全不知道Model的存在:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // 获取共享ViewModel
    val sharedViewModel = ViewModelProvider(this)[SharedStateViewModel::class.java]

    // 通过工厂类给业务ViewModel传入共享ViewModel
    val buttonViewModel = ViewModelProvider(this, ButtonViewModelFactory(sharedViewModel))[ButtonViewModel::class.java]
    val textViewModel = ViewModelProvider(this, TextViewModelFactory(sharedViewModel))[TextViewModel::class.java]

    // 绑定按钮点击事件
    btn_click.setOnClickListener {
        buttonViewModel.onButtonClicked()
    }

    // 观察文本变化并更新UI
    textViewModel.showText.observe(this) { text ->
        tv_display.text = text
    }
}

// 对应的ViewModel工厂类
class ButtonViewModelFactory(private val sharedState: SharedStateViewModel) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(ButtonViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return ButtonViewModel(sharedState) as T
        }
        throw IllegalArgumentException("无法创建未知类型的ViewModel")
    }
}

class TextViewModelFactory(private val sharedState: SharedStateViewModel) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(TextViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return TextViewModel(sharedState) as T
        }
        throw IllegalArgumentException("无法创建未知类型的ViewModel")
    }
}

方案优势

  • 严格遵循MVVM原则:View仅依赖ViewModel,对Model完全无感知
  • 保证Model实例唯一:所有业务ViewModel共享同一Model,状态变化能实时同步
  • 生命周期安全:Model由ViewModel持有,跟随ViewModel的生命周期管理,避免内存泄漏
  • 无额外依赖:无需引入Dagger/Hilt等DI框架,纯Jetpack组件实现

内容的提问来源于stack exchange,提问作者Helkor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:42:37