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
相关产品推荐
相关产品推荐

