You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataStore布尔值获取异常:白金奖励逻辑故障排查求助

问题分析与修复方案

核心错误点梳理

  • 协程异步逻辑误用:原代码提前通过协程获取DataStore值,但异步操作未完成就执行判断逻辑,导致依赖的变量仍是初始值,判断失效。
  • LiveData观察逻辑错误:观察DataStore转换的LiveData时,没有使用回调返回的最新数据,反而依赖未及时更新的外部变量,导致首次触发时判断错误。
  • DataStore管理器笔误:Setter方法里变量名、对象引用都写错了,Getter属性名和Activity调用的名称不匹配,导致读写DataStore都出问题。
  • 全局协程滥用:用GlobalScope执行数据更新操作,脱离Activity生命周期,容易引发内存泄漏。

修复后的DataStore管理器代码

private val Context.singlePlayerPlatinumManager by preferencesDataStore("single_player_platinum_manager")

class singlePlayerPlatinumManager(context: Context) {

    private val singlePlayerPlatinumManager = context.singlePlayerPlatinumManager

    companion object{
        val LEVEL_ONE_PLATINUM_BALL_KEY = booleanPreferencesKey("LEVEL_ONE_PLATINUM_KEY")
        // 其他关卡的key可以在这里扩展
    }

    // 修复Setter的变量引用和参数错误
    suspend fun setLevelOnePlatinum(boolean_levelOnePlatinum: Boolean){
        singlePlayerPlatinumManager.edit{
            it[LEVEL_ONE_PLATINUM_BALL_KEY] = boolean_levelOnePlatinum
        }
    }

    // 修复Getter属性名,和Activity调用保持一致
    val getLevelOnePlatinumBall: Flow<Boolean> = singlePlayerPlatinumManager.data.map{
        it[LEVEL_ONE_PLATINUM_BALL_KEY] ?: false
    }
}

修复后的游戏结束页代码

class endOfGameScreen: AppCompatActivity {

    lateinit var singlePlayerPlatinumManager: singlePlayerPlatinumManager
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_level_completed)
        
        getBackendData()
    }

    fun getBackendData(){
        singlePlayerPlatinumManager = singlePlayerPlatinumManager(this)
        setInGameCurrencyScoresToEndScreen()
    }

    fun setInGameCurrencyScoresToEndScreen(){
        if (int_correctAnswers == int_totalNumberOfQuestions) {
            textview_status.setText("CONGRATULATIONS!")
            icon_platinum.setImageResource(R.drawable.platinum)
            
            // 直接用LiveData回调返回的最新值做判断,不用依赖外部变量
            singlePlayerPlatinumManager.getLevelOnePlatinumBall.asLiveData().observe(this) { isPlatinumEarned ->
                if (isPlatinumEarned) {
                    textview_platinumMessage.setText("Already achieved!")
                } else {
                    val platinumToBeAwarded = 1
                    textview_platinumMessage.setText("You have been awarded 1 Platinum. Congratulations!")
                    // 用lifecycleScope替代GlobalScope,绑定Activity生命周期
                    lifecycleScope.launch {
                        gameCurrencyManager.setPlatinum(int_currentPlatinumTotal + platinumToBeAwarded)
                        singlePlayerPlatinumManager.setLevelOnePlatinum(true)
                    }
                }
            }
        }
    }
}

修复说明

  1. 修正DataStore读写逻辑:把管理器里的笔误全部修正,确保能正确读写白金奖励的状态。
  2. 简化判断逻辑:去掉冗余的boolean_platinumIsEarned变量,直接用LiveData回调的最新值做判断,保证每次判断都基于最新的DataStore数据。
  3. 规范协程使用:用lifecycleScope代替GlobalScope,避免协程在Activity销毁后仍运行,防止内存泄漏。
  4. 移除无效异步操作:不需要提前通过协程获取DataStore值,LiveData会自动监听数据变化并触发回调,逻辑更简洁可靠。

内容的提问来源于stack exchange,提问作者mi-ned32

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:02:50