Composable传递ViewModel时实例化失败的原因排查
问题:调用resetGame方法导致ViewModel实例化失败,应用崩溃
我跟着Android官方教程实现Unscramble应用,创建了GameViewModel并在GameScreen Composable中用viewModel()注入,但始终遇到**「Failed to instantiate a ViewModel」**错误,预览无法渲染且模拟器中应用持续崩溃。已确认写法和官方示例一致,ViewModel相关依赖也配置完整。
通过排查发现,只要注释掉GameViewModel中resetGame方法内的两行代码,ViewModel就能正常实例化;取消注释任意一行,就会触发实例化失败问题。
相关代码
GameScreen Composable
@Composable fun GameScreen( gameViewModel: GameViewModel = viewModel() ) { val gameUiState by gameViewModel.uiState.collectAsState() /* rest of composable */ }
GameViewModel类
package com.example.unscramble.ui import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import com.example.unscramble.data.allWords class GameViewModel : ViewModel() { // Game UI state private val _uiState = MutableStateFlow(GameUiState()) var userGuess by mutableStateOf("") private set // Backing property to avoid state updates from other classes val uiState: StateFlow<GameUiState> = _uiState.asStateFlow() init { resetGame() } fun resetGame() { usedWords.clear() _uiState.value = GameUiState(currentScrambledWord = pickRandomWordAndShuffle()) } private lateinit var currentWord: String // Set of words used in the game private var usedWords: MutableSet<String> = mutableSetOf() private fun pickRandomWordAndShuffle(): String { // Continue picking up a new random word until you get one that hasn't been used before currentWord = allWords.random() if (usedWords.contains(currentWord)) { return pickRandomWordAndShuffle() } else { usedWords.add(currentWord) return shuffleCurrentWord(currentWord) } } private fun shuffleCurrentWord(word: String): String { val tempWord = word.toCharArray() // Scramble the word tempWord.shuffle() while (String(tempWord).equals(word)) { tempWord.shuffle() } return String(tempWord) } }
依赖配置
dependencies { implementation(platform("androidx.compose:compose-bom:2023.08.00")) implementation("androidx.activity:activity-compose:1.8.0") implementation("androidx.compose.material3:material3") implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0") }
核心疑问
为什么resetGame()里的usedWords.clear()或者_uiState.value = GameUiState(...)这两行代码会导致ViewModel实例化失败?需要恢复这部分功能,该如何解决?
内容的提问来源于stack exchange,提问作者devel_dizzie
相关产品推荐
相关产品推荐

