【问题标题】:".contains" returns null pointer exception even when the list has been initialised and the value passed isn't null“.contains”返回空指针异常,即使列表已初始化且传递的值不为空
【发布时间】:2022-06-22 10:17:11
【问题描述】:

android studio screenshot

stack trace image

now working image

上面的屏幕截图有问题代码,todo cmets 将引导您找到问题所在。第 34 行是故障点。我已经在不同的 ide 中分别尝试了带有空列表的代码,它工作得很好。这是我测试的运行良好的代码 -

fun main() {
    val dList = mutableListOf<String>()
    val newString = "hello"
    if (dList.contains(newString)){
        print("contains")
    }else{
        print("does not contain")
    }
}

所以,空列表不是问题。我还尝试从我正在关注的教程中复制粘贴代码[我目前正在学习 kotlin 中的 android studio 基础知识],但也没有用。我什至不知道该尝试什么了。我什至在这里搜索了错误。这是针对具有初始化问题的java。我的没有那个。为了安全起见,我再次执行了前面的步骤,看看我是否遗漏了什么。没有找到任何东西。所以,我被困住了。 屏幕截图中的代码如下 [还包括注释掉的代码] -

package com.example.android.unscramble.ui.game

import android.util.Log
import androidx.lifecycle.ViewModel

class GameViewModel : ViewModel() {
    val TAG = "GameViewModel"

    init {
        Log.d(TAG, "View Model initialised")
        getNextWord()
    }
    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

    override fun onCleared() {
        super.onCleared()
        Log.d("GameViewModel", "game view model destroyed")
    }

    private fun getNextWord() {
        currentWord = allWordsList.random()     //todo - is getting assigned
        Log.d(TAG,"current word = ${currentWord}")  //todo - current word isn't null
        val tempWord = currentWord.toCharArray()
        tempWord.shuffle()
        while (String(tempWord).equals(currentWord, false)) {
            tempWord.shuffle()
        }
        Log.d(TAG,"point - 1")  //todo - gets executed
        if (wordsList.contains(currentWord)){       //todo - point of failure
            Log.d(TAG,"point - 2")      //todo - not getting executed
            getNextWord()
        } else {
            Log.d(TAG,"point - 3")      //todo - not getting executed
            _currentScrambledWord = String(tempWord)
            ++_currentWordCount
            wordsList.add(currentWord)
        }
    }//todo - there isn't anything executable below. all commented out
    /*
    fun getNextWord() {
        currentWord = allWordsList.random()
        Log.d(TAG, "current word = ${currentWord}")
        if (wordsList.contains(currentWord)) {
            Log.d(TAG, "step - 1")
            getNextWord()
        }
        else {
            Log.d(TAG, "step - 2")
            val tempWord = currentWord.toCharArray()
            while (String(tempWord) == currentWord) {
                tempWord.shuffle()
            }
            Log.d(TAG, "step - 3")
            wordsList.add(currentWord)
            _currentScrambledWord = String(tempWord)
            _currentWordCount++
        }
    }
    */
}

【问题讨论】:

  • 能否请您包括实际的堆栈跟踪
  • 是的,刚刚添加。它位于屏幕截图图像下方的顶部。
  • 您是否尝试过将方法调用移出 init 块?
  • 关于那个,你的想法给了我另一个想法。即将初始化代码移动到变量初始化之后。现在,它起作用了。我认为无论变量是否已初始化,init 都会起作用。也许这就是它突然起作用的原因,因为它是在变量初始化后调用的。当前工作代码的图像已添加到堆栈跟踪屏幕截图的正下方。注意初始化代码的位置。这就是我改变的一切。感谢您的帮助。
  • 我已经为你写了一个答案,我过去也有类似的问题

标签: android kotlin


【解决方案1】:

我相信这是因为您的代码的顺序,init 块在其他变量初始化之前执行。如果要将 init 块移动到方法中:

fun foo() {
   Log.d(TAG, "View Model initialised")
   getNextWord()
}

在创建视图模型实例后调用foo,有望解决问题。

或者,将变量的声明移动到 init 块之前也可能会起作用。

类似的问题,我想,here

【讨论】:

    【解决方案2】:

    将初始化位置移动到变量声明的底部(就在 onCleared 函数上方)解决了。

    class GameViewModel : ViewModel() {
        val TAG = "GameViewModel"
    
        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")
        }
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-15
      • 2015-08-16
      • 1970-01-01
      • 2019-03-01
      • 2020-08-14
      • 1970-01-01
      • 2016-10-30
      相关资源
      最近更新 更多