英文:
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("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)
}
}
data store code is
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
}
}```
</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("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)
}
}
for more info about compose : State in Compose
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论