Android Kotlin中已初始化List调用contains传入非空值仍报空指针异常
问题根因
报错核心是Kotlin类初始化顺序错误:
你写的GameViewModel类中,init初始化代码块的书写位置在wordsList等成员变量的定义之前。Kotlin类的初始化逻辑严格按照代码书写的从上到下顺序执行,执行init块内的getNextWord()方法时,wordsList还没有完成初始化赋值,调用wordsList.contains()时就会触发崩溃。
你之前单独测试空列表逻辑没问题,是因为测试代码里列表在调用contains前已经完成了初始化,和当前场景的初始化顺序问题完全不同。
修复方案
把所有成员变量的定义和初始化代码移到init块前面即可,调整后的代码如下:
package com.example.android.unscramble.ui.game import android.util.Log import androidx.lifecycle.ViewModel class GameViewModel : ViewModel() { val TAG = "GameViewModel" // 所有成员变量移到init块之前定义初始化 private var _score = 0 private var _currentWordCount = 0 private lateinit var _currentScrambledWord: String val currentScrambledWord: String get() = _currentScrambledWord private var wordsList: MutableList<String> = mutableListOf() lateinit var currentWord: String init { Log.d(TAG, "View Model initialised") getNextWord() } override fun onCleared() { super.onCleared() Log.d("GameViewModel", "game view model destroyed") } private fun getNextWord() { currentWord = allWordsList.random() Log.d(TAG,"current word = ${currentWord}") val tempWord = currentWord.toCharArray() tempWord.shuffle() while (String(tempWord).equals(currentWord, false)) { tempWord.shuffle() } Log.d(TAG,"point - 1") if (wordsList.contains(currentWord)){ Log.d(TAG,"point - 2") getNextWord() } else { Log.d(TAG,"point - 3") _currentScrambledWord = String(tempWord) ++_currentWordCount wordsList.add(currentWord) } } }
注:如果运行后仍提示
allWordsList未定义,检查该全局单词列表是否在其他文件中正确引入、初始化完成。
内容的提问来源于stack exchange,提问作者Vaishnav Kanhirathingal
相关产品推荐
相关产品推荐

