Android的lateinit问题

我声明了一个全局变量:

lateinit var trueBtn :Button

在activity的onCreate()函数中给它赋值

pos = (1..4).random()       //生成正确单词释义的位置

            withContext(Dispatchers.Main){
                binding.apply {
                when (pos)  {
                    1 -> {
                        mean1.text = wordList[num].tranlation
                        trueBtn = mean1
                    }
                    2 -> {
                        mean2.text = wordList[num].tranlation
                        trueBtn = mean2
                    }
                    3 -> {
                        mean3.text = wordList[num].tranlation
                        trueBtn = mean3
                    }
                    4 -> {
                        mean4.text = wordList[num].tranlation
                        trueBtn = mean4
                    }
                }

在onResume()函数中调用trueBtn的setOnClickListener函数实现功能,但是当我点击启动这一Activity闪退报错
显示:
java.lang.RuntimeException: Unable to resume activity {com.dyk.mysqltest/com.dyk.mysqltest.ui.LearnActivity}: kotlin.UninitializedPropertyAccessException: lateinit property trueBtn has not been initialized
为什么我已经在onCreate中赋值了,它依然报没有初始化的错误?

完整代码如下:



class LearnActivity : BaseActivity() {

    var num = 0
    lateinit var trueBtn :Button
    val selectwords = selectWords()
    private lateinit var wordList :MutableList<Word>

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        val binding = ActivityLearnBinding.inflate(layoutInflater)
        setContentView(binding.root)
        var pos: Int     //position四个选项的位置

        lifecycleScope.launch(Dispatchers.IO) {

            wordList = selectwords.select10words(this@LearnActivity)

            binding.word.text = wordList[num].word

            pos = (1..4).random()       //生成正确单词释义的位置

            withContext(Dispatchers.Main){
                binding.apply {
                when (pos)  {
                    1 -> {
                        mean1.text = wordList[num].tranlation
                        trueBtn = mean1
                    }
                    2 -> {
                        mean2.text = wordList[num].tranlation
                        trueBtn = mean2
                    }
                    3 -> {
                        mean3.text = wordList[num].tranlation
                        trueBtn = mean3
                    }
                    4 -> {
                        mean4.text = wordList[num].tranlation
                        trueBtn = mean4
                    }
                }
                Log.d("BtnBindings","$pos")
                }

            }


            val map = HashMap<Int, Int>()
            for (i in 0..2) {
                var randoms = getRandoms()
                while (map.containsValue(randoms)|| wordList[0].id ==randoms.toLong()){
                    randoms = getRandoms()
                }
                map[i] = randoms
            }

            val othWords = mutableListOf<Word>()
            for (i in 0..2){

                val index : Int= map[i] as Int
                othWords.add(selectwords.selectWordById(this@LearnActivity,index))

            }
            Log.d("othWords","${othWords}")
            withContext(Dispatchers.Main){
                when (pos) {
                    1 -> {
                        binding.mean2.text = othWords[0].tranlation
                        binding.mean3.text = othWords[1].tranlation
                        binding.mean4.text = othWords[2].tranlation
                    }
                    2 -> {
                        binding.mean1.text = othWords[0].tranlation
                        binding.mean3.text = othWords[1].tranlation
                        binding.mean4.text = othWords[2].tranlation
                    }
                    3 -> {
                        binding.mean1.text = othWords[0].tranlation
                        binding.mean2.text = othWords[1].tranlation
                        binding.mean4.text = othWords[2].tranlation
                    }
                    4 -> {
                        binding.mean1.text = othWords[0].tranlation
                        binding.mean2.text = othWords[1].tranlation
                        binding.mean3.text = othWords[2].tranlation
                    }
            }

            }


        }



    }

    override fun onStart() {
        super.onStart()

        Log.d("LearnActivity","onStart")

    }

    override fun onResume() {
        super.onResume()
        val binding = ActivityLearnBinding.inflate(layoutInflater)
        var pos: Int

       
        trueBtn?.setOnClickListener {
            
            if (num<10){
                lifecycleScope.launch (Dispatchers.IO) {


//                    val word = wordList[num]
//                    if (word != null){
//                        word.selected = 1
//                        thread {
//                            Log.d("Test","$num")
//                            val wordDao = AppDatabase.getDatabase(this).wordDao()       //在数据库中修改该单词selected为1
//                            wordDao.updateWord(word)
//                            Log.d("Test","222222222222222222")
//                        }
//                    }

                    withContext(Dispatchers.Main){
                        binding.word.text = wordList[num+1].word
                        pos = (1..4).random()       //生成正确单词释义的位置
                        

                        when (pos)  {                      //正确单词释义按钮文本显示
                            1 -> {
                                binding.mean1.text = wordList[num+1].tranlation
                                trueBtn = binding.mean1
                            }
                            2 -> {
                                binding.mean2.text = wordList[num+1].tranlation
                                trueBtn = binding.mean2
                            }
                            3 -> {
                                binding.mean3.text = wordList[num+1].tranlation
                                trueBtn = binding.mean3
                            }
                            4 -> {
                                binding.mean4.text = wordList[num+1].tranlation
                                trueBtn = binding.mean4
                            }
                        }



                    }



                    val map2 = HashMap<Int, Int>()
                    for (i in 0..2){
                        var randoms = getRandoms()
                        while (map2.contains(randoms)||wordList[num+1].id == randoms.toLong()) {
                            randoms = getRandoms()
                        }
                        map2[i] = randoms
                        Log.d("ClickRandoms","${map2}")
                    }
                    println(map2)
                    val othWords2 = mutableListOf<Word>()

                    for (i in 0..2){
                        var index :Int= map2[i] as Int
                        Log.d("INDEX","$index")
                        var selectWordById = selectwords.selectWordById(this@LearnActivity, index)
                        othWords2.add(selectWordById)

                        //!!!
                    }
                    withContext(Dispatchers.Main){
                        when (pos) {
                            1 -> {
                                binding.mean2.text = othWords2[0].tranlation
                                binding.mean3.text = othWords2[1].tranlation
                                binding.mean4.text = othWords2[2].tranlation
                            }
                            2 -> {
                                binding.mean1.text = othWords2[0].tranlation
                                binding.mean3.text = othWords2[1].tranlation
                                binding.mean4.text = othWords2[2].tranlation
                            }
                            3 -> {
                                binding.mean1.text = othWords2[0].tranlation
                                binding.mean2.text = othWords2[1].tranlation
                                binding.mean4.text = othWords2[2].tranlation
                            }
                            4 -> {
                                binding.mean1.text = othWords2[0].tranlation
                                binding.mean2.text = othWords2[1].tranlation
                                binding.mean3.text = othWords2[2].tranlation
                            }
                        }
                    }
                    Log.d("othWords2","${othWords2}")
                }

                


                if (num<9) {
                    num++
                }else{
                    Log.d("LOOOK","right here")
                    Toast.makeText(this,"你已完成学习任务",Toast.LENGTH_SHORT).show()
                    finish()
                }
                Log.d("Test","$num")
            }
        }
    }

    fun getRandoms(): Int{
        val randoms = (3..13).random()
        println("Randoms: "+randoms)
        return randoms
    }
    

}


这是我毕业设计的代码,自学Android写的不规范,有错误还请斧正

参考GPT和自己的思路:

根据你提供的代码,我可以看到你使用了协程来设置Button的值,这可能是导致问题的原因。lateinit var只有被正确初始化后才能被使用,而协程的运行是异步的,可能会导致在onResume()中调用trueBtn时,它还没有被正确初始化。

为了避免这个问题,建议你在onCreate()中使用普通的同步方法来初始化Button,而不是使用协程,这样可以确保在onResume()中Button已经被正确初始化。

另外,为了避免空指针异常,建议你在onResume()中也要对trueBtn是否被正确初始化进行检查,例如:

if (::trueBtn.isInitialized) {
    trueBtn.setOnClickListener {
        // do something
    }
}

UninitializedPropertyAccessException
属性初始化的错误

参考GPT和自己的思路:

根据你提供的代码和错误信息,我认为问题可能出在onResume()函数中。在Android生命周期中,当活动从后台恢复到前台时,onResume()函数会被调用。在该函数中,你调用了trueBtn的setOnClickListener函数,但是由于意外情况(如系统内存不足),可能导致活动的onCreate()函数没有被完全执行,从而导致trueBtn变量没有被赋值。因此,当你在onResume()函数中尝试访问该变量时会抛出“lateinit property trueBtn has not been initialized”异常。

解决这个问题的方法是,你可以在调用setOnClickListener函数之前添加一个判断语句,判断是否已经赋值过,如果没有,就不调用该函数。你可以像下面这样修改你的代码:

if (::trueBtn.isInitialized) {
    trueBtn.setOnClickListener {
        // 点击事件的处理逻辑
    }
}

这样,当trueBtn变量已经被赋值过时,才会执行setOnClickListener函数,避免出现未初始化的异常。

你为什么要用协程来初始化?

可否贴出完整代码

img

你写的是延迟初始化,需要有个初始化时机问题,不显式调用,是不会自动初始化的。

"协程用的出神入化"。Dispatchers.IO属于io密集型,这里有io操作没?