Home > OS >  How to load instantly data from data store?
How to load instantly data from data store?

Time:08-20

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.

CodePudding user response:

In your DataStore, you can do this:

    val readBoolean: Flow<Boolean> = dataStore.data
    .catch { exception ->
        if (exception is IOException) {
            println(exception.message.toString())
            emit(emptyPreferences())
        } else {
            throw exception
        }
    }
    .map { preference ->
        val userBoolean: Boolean =
            preference[PreferenceKeys.booleanPreferencesKey] ?: false
        userBoolean
    }

suspend fun saveBoolean(boolean: Boolean) {
    dataStore.edit { preference ->
        preference[PreferenceKeys.booleanPreferencesKey] = boolean

    }
}

You can put it in your viewModel as liveData like this:

 val readBoolean= dataStore.readBoolean.asLiveData()

 fun saveBoolean(myBoolean: Boolean) = viewModelScope.launch {
        dataStore.saveBoolean(myBoolean)
    }

CodePudding user response:

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.

  • Related