变量在分配数字后似乎没有改变

问题描述 投票:0回答:1

我正在尝试将生命数量纳入测验。似乎发生的情况是,首选项数据存储中的生命数存储到变量中,但当在测验中实际使用它时,它似乎与初始变量值 1 没有任何变化。

class ActivityGame : AppCompatActivity() {

    var int_lives: Int = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_question_multiple_choice_question)

        gameCurrencyManager = gameCurrencyManager(this)
        setInGameCurrencyFromGameCurrencyManager()

        loadQuestion()
    }

    fun loadQuestion(){

        Log.d("tag_NumberOfLives", int_lives.toString())

        if(int_energyDrinksTotal <= 0){
              //Message Dialog Box
        }
    }

   fun setInGameCurrencyFromGameCurrencyManager(){
       
        gameCurrencyManager.getLives.asLiveData().observe(this) {
            int_lives = it
            Log.d("tag_NumberOfLivesToBeAdded", int_lives.toString())
            textview_lives.setText("$int_lives", TextView.BufferType.EDITABLE)
        }
    }
}

这导致“tag_NumberOfLivesToBeAdded”打印出 5,正如预期的那样;然而,当谈到“tag_NumberOfLives”时,一旦测验开始运行,结果就是 1。

我尝试将变量 int_lives 设置为 Delegates.notNull() 但这导致了异常,但因为我无法将变量设置为 Lateinit。

kotlin preferences datastore
1个回答
0
投票

观察实时数据是异步的,因此在调用

loadQuestion()
函数之后,将来会稍微设置变量。

快速但肮脏的解决方案是通过在流程上使用

runBlocking
first()
来读取首选项。您不应该像这样在主线程上读取文件,但您的首选项文件可能很小,并且不会面临明显冻结应用程序的风险。仅当您只需要在每次活动启动时读取一次该值(而不是每次向首选项写入新值时)时,这样做才有意义,这里似乎就是这种情况。

fun setInGameCurrencyFromGameCurrencyManager(){
    int_lives = runBlocking {
      gameCurrencyManager.getLives.first()
    }
    Log.d("tag_NumberOfLivesToBeAdded", int_lives.toString())
    textview_lives.setText("$int_lives", TextView.BufferType.EDITABLE)
}

更正确的方法是等待值到达然后才开始使用它:

class ActivityGame : AppCompatActivity() {

    var int_lives: Int = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleScope.launch {
            int_lives = gameCurrencyManager.getLives.first()
            startGame()
        }
    }
            
    private fun startGame() {
        setContentView(R.layout.activity_question_multiple_choice_question)
        textview_lives.setText("$int_lives", TextView.BufferType.EDITABLE)
        loadQuestion()
    }

    //…
}

如果您认为数据需要一段时间才能加载,您可以在启动协程之前设置一个显示某种加载屏幕的内容视图。

© www.soinside.com 2019 - 2024. All rights reserved.