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

Jetpack Compose中ViewModel出现NoSuchMethodException问题求助

解决Jetpack Compose中ViewModel的NoSuchMethodException错误

问题描述

运行Jetpack Compose项目时触发FATAL EXCEPTION: main,报错信息为:

java.lang.NoSuchMethodException: com.mydummy.viewmodeltesting.DummyViewModel.<init> []

已在Android Studio全新EmptyActivity项目中复现该问题,相关代码如下:

MainActivity.kt

class MainActivity : ComponentActivity() {
    val viewModel: DummyViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ViewModelTestingTheme {
                val data by viewModel.dataState.collectAsState()
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
                    ShowDataList(dataList = data)
                }
            }
        }
    }
}

@Composable
fun ShowDataList(dataList: List<DummyMetadata>, modifier: Modifier = Modifier) {
    Box(modifier = Modifier.fillMaxSize()) {
        LazyColumn(modifier = Modifier) {
            items(dataList) { data -> ShowDataItem(model = data)}
        }
    }
}

@Composable
fun ShowDataItem(model: DummyMetadata) {
    Card(shape = RoundedCornerShape(8.dp), modifier = Modifier) {
        Text(text = model.title)
    }
}

DummyViewModel.kt

class DummyViewModel(private val _repository: DummyRepository): ViewModel() {
    private val _dataState = MutableStateFlow<List<DummyMetadata>>(emptyList())
    val dataState: StateFlow<List<DummyMetadata>> = _dataState

    init {
        fetchData()
    }

    private fun fetchData() {
        viewModelScope.launch {
            try {
                val data = _repository.collectDummyData()
                _dataState.value = data
            } catch (e: Exception) {
                // TODO Error handling or at least better logging
                e.printStackTrace()
            }
        }
    }
}

DummyRepository.kt

class DummyRepository {
    suspend fun collectDummyData(): List<DummyMetadata> {
        return listOf(
            DummyMetadata("First dummy"),
            DummyMetadata("Second dummy"),
            DummyMetadata("Last dummy")
        )
    }
}

DummyMetadata.kt

data class DummyMetadata(
    val title: String
)

问题原因

ViewModel的实例化由ViewModelProvider负责,默认的ViewModelProvider.Factory会尝试调用ViewModel的无参构造函数。但当前DummyViewModel仅提供了带DummyRepository参数的构造函数,系统找不到无参构造方法,因此抛出NoSuchMethodException。

解决方法

提供以下两种可行方案:

方案1:为ViewModel添加无参构造函数

修改DummyViewModel,给构造函数的参数设置默认值,自动生成无参构造逻辑:

class DummyViewModel(private val _repository: DummyRepository = DummyRepository()): ViewModel() {
    // 原有代码保持不变
}

方案2:自定义ViewModelFactory

通过自定义Factory来控制ViewModel的实例化过程,手动传入Repository依赖:

  1. 创建Factory类:
class DummyViewModelFactory : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(DummyViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return DummyViewModel(DummyRepository()) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
  1. 在MainActivity中指定Factory初始化ViewModel:
val viewModel: DummyViewModel by viewModels { DummyViewModelFactory() }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:10:27