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依赖:
- 创建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") } }
- 在MainActivity中指定Factory初始化ViewModel:
val viewModel: DummyViewModel by viewModels { DummyViewModelFactory() }
内容的提问来源于stack exchange,提问作者Windowlicker
相关产品推荐
相关产品推荐

