Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

1.1K
Vistas
Why there is multiple Datastore is created?

java.lang.IllegalStateException: There are multiple DataStores active for the same file: /data/user/0/com.firstgoalkeeper.firstgoalkeeper/files/datastore/player_pref.preferences_pb. You should either maintain your DataStore as a singleton or confirm that there is no two DataStore's active on the same file (by confirming that the scope is cancelled).

class Constants {
    companion object{
     const val PLAYER_PREFERENCE = "player_pref"
        val PLAYER_SELECTION_KEY = intPreferencesKey("player_selection")
    }
}
    
abstract class PrefsDataStore(context: Context, fileName: String) {
    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
        fileName
    )

    val mdataStore: DataStore<Preferences> = context.dataStore
}

class PlayerSelectionDataStore(context: Context) : PrefsDataStore(context, 
    PLAYER_PREFERENCE) {


    suspend fun storeIndex(index: Int) {
         mdataStore.edit {
            it[PLAYER_SELECTION_KEY] = index
        }
    }

    val userSelectionFlow: Flow<Int> = mdataStore.data.map {
        it[PLAYER_SELECTION_KEY] ?: 4
    }
}


@Composable
fun PlayerSelection() {
    val context = LocalContext.current
    val playerSelectionDataStore = PlayerSelectionDataStore(context)

    var index by remember {
        mutableStateOf(4)
    }
   


    Log.d("index", "PlayerSelection: we are at index ${index} ")
    Log.d("index", "PlayerSelection: we select ${allTeamsLists[index].name} ")

    Row(
        verticalAlignment = Alignment.CenterVertically, modifier = Modifier
            .fillMaxSize()
            .background(color = goalkeeperBackground)
    ) {
    // ...
        Box(
            modifier = Modifier
                .clickable {
                    GlobalScope.launch {
                        playerSelectionDataStore.storeIndex(index)

                    }
                    Toast
                        .makeText(
                            context,
                            "${allTeamsLists[index].name} player is Selected ",
                            Toast.LENGTH_SHORT
                        )
                        .show()
                }
                ...
        ) {...}

What i did wrong and suggest best practice.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Right not you're creating a new PlayerSelectionDataStore object on each recomposition.

The least you can do is wrapping it with remember:

val playerSelectionDataStore = remember(context) { PlayerSelectionDataStore(context) }

A more general solution:

@Composable
fun <T> rememberPreference(
    key: Preferences.Key<T>,
    defaultValue: T,
): MutableState<T> {
    val coroutineScope = rememberCoroutineScope()
    val context = LocalContext.current
    val state = remember {
        context.dataStore.data
            .map {
                it[key] ?: defaultValue
            }
    }.collectAsState(initial = defaultValue)

    return remember {
        object : MutableState<T> {
            override var value: T
                get() = state.value
                set(value) {
                    coroutineScope.launch {
                        context.dataStore.edit {
                            it[key] = value
                        }
                    }
                }

            override fun component1() = value
            override fun component2(): (T) -> Unit = { value = it }
        }
    }
}

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "preferences")

Usage:

var text by rememberPreference(stringPreferencesKey("key_text"), defaultValue = "World")
TextField(value = text, onValueChange = { text = it })
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda