Попытка вызвать метод интерфейса для нулевой ссылки на объект в kotlin
После внедрения моделей просмотра в приложение для создания реактивного ранца, когда я запускаю приложение, оно показывает ошибку: -
Попытка вызвать метод интерфейса 'boolean java.util.Set.contains(java.lang.Object)' для нулевой ссылки на объект java.lang.NullPointerException: попытка вызвать метод интерфейса 'boolean java.util.Set.contains(java.lang.Object)» в ссылке на нулевой объект в com.example.android.ui.GameViewModel.pickRandomWordAndShuffle(GameViewModel.kt:21) в com.example.android.ui.GameViewModel.(GameViewModel.kt:10)
вот мой код: -
import androidx.lifecycle.ViewModel
import com.example.android.unscramble.data.allWords
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
class GameViewModel : ViewModel() {
private val _uiState =
MutableStateFlow(GameUiState(currentScrambledWord = pickRandomWordAndShuffle()))
val uiState: StateFlow<GameUiState> = _uiState.asStateFlow()
private var _count = 0
val count: Int
get() = _count
private lateinit var currentWord: String
private var usedWords: MutableSet<String> = mutableSetOf()
private fun shuffleCurrentWord(word: String): String {
val tempWord = word.toCharArray()
// Scramble the word
tempWord.shuffle()
while (String(tempWord) == word) {
tempWord.shuffle()
}
return String(tempWord)
}
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 resetGame() {
usedWords.clear()
_uiState.value = GameUiState(currentScrambledWord = pickRandomWordAndShuffle())
}
init {
resetGame()
}
}
Он не показывает никаких ошибок времени компиляции. Я не знаю, что мне делать.
1 ответ
Вы инициализируете перед инициализацией . Это вызываетpickRandomWordAndShuffle()
до того, как был инициализирован, поэтому он все ещеnull
в создаваемом экземпляре.
Если вы переместите декларациюusedWords
выше должно работать.
ОДНАКО: как правило, плохая идея вызывать функции-члены до того, как экземпляр будет полностью инициализирован, именно по этой причине.
Вы могли бы сделать_uiState
и lazy , что сделало бы это безопаснее. Например:
// Copyright 2023 Google LLC.
// SPDX-License-Identifier: Apache-2.0
private val _uiState by lazy {
MutableStateFlow(GameUiState(currentScrambledWord = pickRandomWordAndShuffle()))
}
val uiState: StateFlow<GameUiState> by lazy { _uiState.asStateFlow() }
который будет ждать, пока что-то не используетuiState
(что, глядя на ваш код, происходит только извне, поэтому вам будет гарантировано, что он не будет инициализирован до тех пор, покаGameViewModel
был полностью инициализирован.