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) } } } } } }
修复说明
- 修正DataStore读写逻辑:把管理器里的笔误全部修正,确保能正确读写白金奖励的状态。
- 简化判断逻辑:去掉冗余的
boolean_platinumIsEarned变量,直接用LiveData回调的最新值做判断,保证每次判断都基于最新的DataStore数据。 - 规范协程使用:用
lifecycleScope代替GlobalScope,避免协程在Activity销毁后仍运行,防止内存泄漏。 - 移除无效异步操作:不需要提前通过协程获取DataStore值,LiveData会自动监听数据变化并触发回调,逻辑更简洁可靠。
内容的提问来源于stack exchange,提问作者mi-ned32
相关产品推荐
相关产品推荐

