Please help me figure out how to instantly load a stored value from DataStore As I understand when I have try to get Data after reloading app the first seconds the value will be initial(false) and only then will become true (if true was stored).
Code snippet's:
class StoreManager(private val context: Context) {
companion object {
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore("store_sample")
val BOOLEAN_KEY = booleanPreferencesKey("BOOLEAN_KEY")
}
suspend fun saveBoolean(value: Boolean) {
context.dataStore.edit {
it[BOOLEAN_KEY] = value
}
}
val booleanData: Flow<Boolean> = context.dataStore.data.map {
it[BOOLEAN_KEY] ?: false
}}
And incomplite @Composable fun
@Composable
fun GpsScreen() {
val storeManager = StoreManager(LocalContext.current)
val coroutineScope = rememberCoroutineScope()
val newData = storeManager.booleanData.collectAsState(initial = false)
Button(
onClick = {
// DataStore
coroutineScope.launch {
storeManager.saveBoolean(isDecimalPosition)
}
},
modifier = Modifier
.fillMaxWidth()
.padding(PADDING_BIG)
.align(Alignment.CenterHorizontally)
) {
Text(
textAlign = TextAlign.Center,
text = "TXT"
)
}}
The code is not complete but works fine. The only thing is not clear what to do to instantly load the desired value.
You load datastore "instantly" i.e. synchronously by blocking the thread using runBlocking
.
class StoreManager(private val context: Context) {
companion object {
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore("store_sample")
val BOOLEAN_KEY = booleanPreferencesKey("BOOLEAN_KEY")
}
suspend fun saveBoolean(value: Boolean) {
context.dataStore.edit {
it[BOOLEAN_KEY] = value
}
}
val booleanData = MutableStateFlow(false)
// Call this whenever you want to load booleanData
// You could make the booleanData to listen to change by collecting the flow after calling loadBoolean()
fun loadBoolean() {
runBlocking {
booleanData.value = context.dataStore.data.map {
it[BOOLEAN_KEY] ?: false
}.first()
}
}
}
@Composable
fun GpsScreen() {
val storeManager = remember { StoreManager(LocalContext.current) }
LaunchedEffect(Unit) {
storeManager.loadBoolean()
}
val coroutineScope = rememberCoroutineScope()
val newData = storeManager.booleanData
Button(
onClick = {
// DataStore
coroutineScope.launch {
storeManager.saveBoolean(isDecimalPosition)
}
},
modifier = Modifier
.fillMaxWidth()
.padding(PADDING_BIG)
.align(Alignment.CenterHorizontally)
) {
Text(
textAlign = TextAlign.Center,
text = "TXT"
)
}
}
Disclaimer: It has a chance to block your UI thread long enough (if the data is relatively huge or something) and cause ANR.
On the other hand, you could provide a loading screen for the user when you are loading the data from the datastore.