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

如何在KMM Compose UI中实现MVVM架构?依赖同步报错求助

KMM Compose 中实现 MVVM 的可行方案及依赖报错解决

依赖报错原因

你添加的androidx.lifecycle.viewmodel.ktx、androidx.activity.ktx等依赖都是Android平台专属的,不能直接放在commonMain的依赖配置中——iOS没有对应的实现,所以Gradle同步时会在iOS目标平台(如iosArm64)找不到依赖文件,触发ArtifactResolveException错误。

跨平台 MVVM 实现方案

核心思路是:将ViewModel的业务逻辑、状态管理放在commonMain中共享,平台相关的生命周期适配分Android/iOS各自处理。


1. 定义跨平台的ViewModel基类(commonMain)

实现一个轻量的、不依赖AndroidX的基类,处理协程生命周期:

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel

open class SharedViewModel {
    // 跨平台协程作用域,ViewModel销毁时自动取消
    protected val viewModelScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)

    // 销毁回调,用于清理资源
    open fun onCleared() {
        viewModelScope.cancel()
    }
}

2. 定义共享的UI状态与事件(commonMain)

用不可变数据类管理UI状态,密封类统一处理UI事件:

// UI状态:所有需要展示的数据都封装在这里
data class CounterState(val count: Int = 0)

// UI事件:定义用户交互的所有类型
sealed class CounterEvent {
    object Increment : CounterEvent()
    object Decrement : CounterEvent()
}

3. 实现业务ViewModel(commonMain)

用StateFlow管理状态,确保状态变化能被UI层感知:

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

class CounterViewModel : SharedViewModel() {
    // 内部可变状态,对外暴露不可变的StateFlow
    private val _state = MutableStateFlow(CounterState())
    val state = _state.asStateFlow()

    // 处理UI事件,更新状态
    fun handleEvent(event: CounterEvent) {
        when (event) {
            CounterEvent.Increment -> {
                _state.value = _state.value.copy(count = _state.value.count + 1)
            }
            CounterEvent.Decrement -> {
                _state.value = _state.value.copy(count = _state.value.count - 1)
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        _state.resetReplayCache() // 可选:清理状态缓存
    }
}

4. Android端整合Compose与生命周期

将共享ViewModel包装成AndroidX ViewModel,借助其自动生命周期管理:

  • 首先在androidMain的依赖中添加AndroidX相关库(不要放在commonMain):
androidMain.dependencies {
    implementation(libs.androidx.lifecycle.viewmodel.ktx)
    implementation(libs.androidx.lifecycle.viewmodel.compose)
    implementation(libs.androidx.activity.compose)
}
  • 在Compose中使用:
// 包装成AndroidX ViewModel
class AndroidCounterViewModel : androidx.lifecycle.ViewModel(), CounterViewModel by CounterViewModel()

@Composable
fun CounterScreen() {
    val viewModel = viewModel<AndroidCounterViewModel>()
    // 自动感知生命周期的状态收集
    val state by viewModel.state.collectAsStateWithLifecycle()

    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "Count: ${state.count}")
        Button(onClick = { viewModel.handleEvent(CounterEvent.Increment) }) {
            Text("Increment")
        }
        Button(onClick = { viewModel.handleEvent(CounterEvent.Decrement) }) {
            Text("Decrement")
        }
    }
}

5. iOS端适配生命周期

iOS没有AndroidX ViewModel的自动生命周期管理,需要手动调用销毁方法:

import UIKit
import shared // 替换为你的KMM共享模块名称

class CounterViewController: UIViewController {
    private let viewModel = CounterViewModel()
    private var stateObserver: NSObjectProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()
        // 监听StateFlow状态变化,更新UI
        stateObserver = viewModel.state.subscribe { [weak self] state in
            guard let self = self, let state = state else { return }
            self.countLabel.text = "Count: \(state.count)"
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 销毁ViewModel,取消协程
        viewModel.onCleared()
        if let observer = stateObserver {
            NotificationCenter.default.removeObserver(observer)
        }
    }

    // 按钮点击事件
    @IBAction func incrementTapped(_ sender: UIButton) {
        viewModel.handleEvent(event: CounterEventIncrement())
    }

    @IBAction func decrementTapped(_ sender: UIButton) {
        viewModel.handleEvent(event: CounterEventDecrement())
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:05:22