The setup below seems straight-forward (to me) but fails with FATAL EXCEPTION: main
due to java.lang.NoSuchMethodException: com.mydummy.viewmodeltesting.DummyViewModel.<init> []
.
That's interesting. The init()
method is there. I also tested this with a completely new EmptyActivity
project in Android Studio, which has the following setup.
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")
)
}
}
And the data class in DummyMetadata.kt is:
data class DummyMetadata(
val title: String
)
That's all. The ViewModel class and the associated Repository & data model look fine. Don't they?
java.lang.NoSuchMethodException: com.mydummy.viewmodeltesting.DummyViewModel.<init> [].
It means that there isn't a no-argument constructor available. by viewModels()
seems not to be able to create this view model instance without a custom factory