有没有办法设置数据存储首选项值的最小值和最大值?

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

我想知道是否可以确保 userManager (或 Datastore 等)类中的值不低于 0 且不高于 5。如果没有的话我该怎么办?

class userManager(context: Context) {

    private val datastore = context.datastore

    companion object {
        val NUMBER_OF_LIVES_KEY = intPreferencesKey("number_of_lives")
    }

    suspend fun setNumberOfLives(numberOfLives: Int){
        datastore.edit {
            it[NUMBER_OF_LIVES_KEY] = numberOfLives
        }
    }

    val getNumberOfLives: Flow<Int> = datastore.data.map {

        if(it[NUMBER_OF_LIVES_KEY]!! > 5){
            it[NUMBER_OF_LIVES_KEY] == 5
        }

        else if(it[NUMBER_OF_LIVES_KEY]!! < 0){
            it[NUMBER_OF_LIVES_KEY] == 0
        }

        it[NUMBER_OF_LIVES_KEY] ?: 5
    }

}

我尝试了 if 语句,它给了我一个“java.lang.NullPointerException”错误消息。

android kotlin preferences datastore
1个回答
0
投票

https://kotlinlang.org/docs/null-safety.html#the-operator很好地描述了当你使用

!!
时会发生什么:

[...]如果你想要一个NPE,你可以拥有它,但你必须明确要求它,它不会突然出现。

其中 NPE 代表

NullPointerException
,即您遇到的错误。

解决方案很简单:如果您不希望代码因此类异常而中止,请删除

!!
。这样,编译器将首先阻止您编译错误的代码,并强制您在运行之前修复它。

根本问题是您尝试访问的属性不存在。如果应用程序是新安装的或用户擦除了所有数据,这是完全正常的。相反,您想要做的是通过在这种情况下提供默认值来优雅地处理这种情况。实际上,您已经在最后一行代码中执行了此操作,但如果您想事先使用该值,那就太晚了。

现在还有另一个问题,你的 getter 在某些情况下实际上也会保存数据。相反,我建议您将更改首选项值的所有内容移至 setter 方法中:

suspend fun setNumberOfLives(numberOfLives: Int){
    datastore.edit {
        if (numberOfLives > 5) {
            it[NUMBER_OF_LIVES_KEY] == 5
        }

        else if (numberOfLives < 0) {
            it[NUMBER_OF_LIVES_KEY] == 0
        }

        else {
            it[NUMBER_OF_LIVES_KEY] = numberOfLives
        }
    }
}

这可以大大简化:

suspend fun setNumberOfLives(numberOfLives: Int) {
    datastore.edit {
        it[NUMBER_OF_LIVES_KEY] = numberOfLives.coerceIn(0, 5)
    }
}

现在你的 getter 只检索首选项值并处理不存在的情况:

val getNumberOfLives: Flow<Int> = datastore.data.map {
    it[NUMBER_OF_LIVES_KEY] ?: 5
}

这样代码更简洁,不易出错。

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