Jetpack Compose数据存储检索失败的可能原因是什么?

huangapple go评论50阅读模式
英文:

What could be causing Jetpack Compose data store retrieval failure?

问题

我正在使用Jetpack Compose中的数据存储来存储字符串值,并根据该字符串进行导航,但我无法从数据存储中获取任何数据。请有人帮助。

composable(AuthDestinations.INFO){
    val context = LocalContext.current
    val pref = Preferences(context)
    var startDes = false
    val scope = rememberCoroutineScope()
    val googleAuthUiClient by lazy {
        GoogleAuthUiClient(
            context = context.applicationContext,
            oneTapClient = Identity.getSignInClient(context.applicationContext)
        )
    }
    LaunchedEffect(true){
        startDes = pref.getData(Constraints.loginStatus)
        // 在此处 startDes = true
    }
    // 在此处 startDes = false
    Log.w("userPageStatus","$startDes,${googleAuthUiClient.getSignedInUser()}")
    if (!startDes){
        InformationScreen(modifier = modifier) {
            navController.navigate(AuthDestinations.LOGIN)
            scope.launch {
                pref.saveBooleanData(Constraints.loginStatus,true)
            }
        }
    }else{
        navController.navigate(AuthDestinations.LOGIN)
    }
}

数据存储代码如下:

private val Context.dataStore : DataStore<Preferences> by preferencesDataStore("pg_rooms")

class Preferences(private val context : Context) {

    suspend fun saveBooleanData(key : Preferences.Key<Boolean>, value : Boolean){
        context.applicationContext.dataStore.edit { preferences->
            preferences[key] = value
        }
    }

    suspend fun getData(key : Preferences.Key<Boolean>): Boolean{
        val data  = context.applicationContext.dataStore.data.first()
        return data[key] ?: false
    }
}
英文:

i am using data store in jetpack compose to store string value
and depending on that string i am navigating but i am not able to get any data from data store
any one please help

composable(AuthDestinations.INFO){
                val context = LocalContext.current
                val pref = Preferences(context)
                var startDes = false
                val scope = rememberCoroutineScope()
                val googleAuthUiClient by lazy {
                    GoogleAuthUiClient(
                        context = context.applicationContext,
                        oneTapClient = Identity.getSignInClient(context.applicationContext)
                    )
                }
                LaunchedEffect(true){
                    startDes = pref.getData(Constraints.loginStatus)
                    //inside startDes = true
                }
             //  outside startDes = false
                Log.w(&quot;userPageStatus&quot;,&quot;$startDes,${googleAuthUiClient.getSignedInUser()}&quot;)
                if (!startDes){
                    InformationScreen(modifier = modifier) {
                        navController.navigate(AuthDestinations.LOGIN)
                        scope.launch {
                            pref.saveBooleanData(Constraints.loginStatus,true)
                        }
                    }
                }else{
                    navController.navigate(AuthDestinations.LOGIN)
                }
            }

data store code is

private val Context.dataStore : DataStore&lt;Preferences&gt; by preferencesDataStore(&quot;pg_rooms&quot;)
class Preferences(private val context : Context) {


    suspend fun saveBooleanData(key :  Preferences.Key&lt;Boolean&gt;, value : Boolean){
            context.applicationContext.dataStore.edit {preferences-&gt;
                preferences[key] = value
            }
    }

    suspend fun getData(key : Preferences.Key&lt;Boolean&gt;): Boolean{
        val data  = context.applicationContext.dataStore.data.first()
        return data[key] ?: false
    }
}```


</details>


# 答案1
**得分**: 0

你实现的数据存储方式看起来没问题。但是你更新 `startDes` 变量的方式不可变且在 Compose 中不可观察,所以你不会立即在你的 Composable 中看到更新后的值。因此,你应该使用 `remember` 函数在你的 Composable 中创建一个可变且可观察的状态。以下是代码片段:

```kotlin
composable(AuthDestinations.INFO) {
    val context = LocalContext.current
    val pref = Preferences(context)
    val startDes = remember { mutableStateOf(false) } // 在这里创建可变状态
    val scope = rememberCoroutineScope()
    val googleAuthUiClient by lazy {
        GoogleAuthUiClient(
            context = context.applicationContext,
            oneTapClient = Identity.getSignInClient(context.applicationContext)
        )
    }
    LaunchedEffect(Unit) { // 以 Unit 作为键,以确保此效果只运行一次
        startDes.value = pref.getData(Constraints.loginStatus)
    }
    Log.w("userPageStatus", "${startDes.value}, ${googleAuthUiClient.getSignedInUser()}")
    if (!startDes.value) {
        InformationScreen(modifier = modifier) {
            navController.navigate(AuthDestinations.LOGIN)
            scope.launch {
                pref.saveBooleanData(Constraints.loginStatus, true)
            }
        }
    } else {
        navController.navigate(AuthDestinations.LOGIN)
    }
}

有关 Compose 的更多信息,请参阅Compose 中的状态

英文:

the way you implemented Data store looks fine, the way you're updating the startDes variable, it's not mutable and not observable in compose, so you won't see the updated value in your composable immediately. so you should use the remember function to create a mutable and observable state in your composable. here is the code snippet :

composable(AuthDestinations.INFO){
    val context = LocalContext.current
    val pref = Preferences(context)
    val startDes = remember { mutableStateOf(false) }  // creating a mutable state here
    val scope = rememberCoroutineScope()
    val googleAuthUiClient by lazy {
        GoogleAuthUiClient(
            context = context.applicationContext,
            oneTapClient = Identity.getSignInClient(context.applicationContext)
        )
    }
    LaunchedEffect(Unit){  // Pass Unit as key to make sure this effect only runs once
        startDes.value = pref.getData(Constraints.loginStatus)
    }
    Log.w(&quot;userPageStatus&quot;,&quot;${startDes.value}, ${googleAuthUiClient.getSignedInUser()}&quot;)
    if (!startDes.value){
        InformationScreen(modifier = modifier) {
            navController.navigate(AuthDestinations.LOGIN)
            scope.launch {
                pref.saveBooleanData(Constraints.loginStatus,true)
            }
        }
    }else{
        navController.navigate(AuthDestinations.LOGIN)
    }
}

for more info about compose : State in Compose

huangapple
  • 本文由 发表于 2023年5月28日 18:47:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76351087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定