Jetpack DataStore en Android

Jetpack DataStore es una solución de almacenamiento de datos que utiliza búferes de protocolo para almacenar pares clave-valor u objetos escritos. DataStore almacena datos de forma asíncrona, confiable y transaccional mediante corrutinas de Kotlin y Flow. En este artículo, veremos por qué necesitamos Preferencias de DataStore de Jetpack, cómo crearlas en nuestra aplicación de Android y cómo mover nuestras Preferencias compartidas a Preferencias de DataStore.

En el blog se tratarán los siguientes temas:

  1. ¿Por qué debería usar Jetpack DataStore?
  2. Preferencias de DataStore frente a SharedPreferences
  3. Implementación de preferencias de Jetpack DataStore
  4. Transferencia de SharedPreferences a Preferencias de DataStore

Pero, ante todo: 

1. ¿Por qué hay un nuevo Jetpack DataStore?

Según la documentación oficial:

  • Jetpack DataStore es un almacén de datos persistente y mejorado, que está aquí para revolucionar la forma en que almacenamos las preferencias.
  • Está basado en Coroutines y Flows en Kotlin.
  • Los datos se guardan de forma asíncrona, consistente y transaccional, eliminando la mayoría de las deficiencias de SharedPreferences.

Las mejoras mencionadas anteriormente son fantásticas.

Ejemplo: se supone que está trabajando en una aplicación de Android con una gran cantidad de descargas, que el programa está disponible en Google Play y que ha sufrido varias actualizaciones y parches de errores a lo largo del tiempo. Como resultado, la aplicación comenzó a recibir ANR en algún momento (La aplicación no responde ). La causa de ANR es que el programa está realizando una operación de ejecución prolongada en el subproceso de interfaz de usuario. (Más de 5 segundos)

2. ¿Cuál fue el propósito de este ANR?

El principal problema era que nuestro archivo de preferencias compartidas había crecido demasiado a medida que continuábamos agregando nuevos pares clave-valor uno por uno. En el subproceso de la interfaz de usuario, intentábamos recuperar el valor de una clave específica tan pronto como se iniciaba el programa. Sin embargo, cuando visita SharedPreferences por primera vez, lee el archivo completo y carga el contenido en la memoria. Y esto estaba ocurriendo en UI Thread para nosotros.

Esta es una operación de entrada/salida. Puede llevar algo de tiempo. En nuestro caso, estaba conduciendo a ANR para el archivo más grande. Además, la implementación actual de Jetpack DataStore desalienta la lectura de datos en el subproceso de la interfaz de usuario. Este fue uno de mis aspectos favoritos. Y ahora, estamos integrando Jetpack DataStore en nuestra aplicación. Comparemos las Preferencias Compartidas con las Preferencias del Almacén de Datos

Preferencias del almacén de datos

Preferencias compartidas

Tiene API asíncrona Puede hacer llamadas API asíncronas
Esto no está recomendado por las Preferencias de DataStore. SharedPreferences proporciona una API síncrona simple; sin embargo, no es seguro usarla en el subproceso de la interfaz de usuario.
Las preferencias de DataStore garantizan la coherencia. Esto, por el contrario, no garantiza que la consistencia
Las preferencias de DataStore permiten el manejo de errores Sin manejo de errores en SharedPrefs
Las preferencias de DataStore son compatibles de forma predeterminada con la API de flujo de rutinas de Kotlin. Las preferencias compartidas necesitan una configuración adicional para hacer que las corrutinas fluyan.

3. Implementación de preferencias de Jetpack DataStore

Incluya la siguiente dependencia en el archivo build.gradle de su aplicación.

implementation "androidx.datastore:datastore-preferences:1.0.0"

GeekTip : Siempre trate de usar la última versión.

Ahora, de manera similar al objeto SharedPreferences, debemos construir el objeto DataStore Preferences.

Kotlin

val gfgDataStore: DataStore<Preferences> =
    context.createDataStore(name = "gfg-datastore")
    // A data store object sample

Luego construimos dos funciones de extensión para leer y escribir datos. Esto es solo para su conveniencia.

Kotlin

fun <gfg> DataStore<Preferences>.getValueFlow(
    your_key: Preferences.Key<gfg>,
    someDefaultValue: gfg
    // Value is gfg here
): Flow<gfg> {
    return this.data
        .catch { exception ->
            if (exception is IOException) {
                emit(emptyPreferences())
            } else {
                // Exception handling
                throw exception
            }
        }.map { preferences ->
            preferences[your_key] ?: someDefaultValue
        }
}
  
suspend fun <gfg> DataStore<Preferences>.setValue(your_key: Preferences.Key<gfg>, value: gfg) {
    this.edit { preferences ->
        preferences[your_key] = value
    }
}

Luego, como se ve a continuación, establecemos Claves de Preferencias:

Kotlin

companion object {
    private val GEEKSFORGEEKS = preferencesKey<String>("spandan-saxena")
}

Ahora, así es como leemos los siguientes datos de las Preferencias de DataStore:

Kotlin

sampleViewModel.launch {
    dataStore.getValueFlow(GEEKSFORGEEKS, "")
        .collect { value ->
            // get the value and then use it
        }
}

Podemos manejar el problema en este caso usando el operador catch en el flujo.

Kotlin

sampleViewModel.launch {
    dataStore.getValueFlow(GEEKSFORGEEKS, "")
        .catch {
            // exception handling
        }
        .collect { value ->
            // collect the value
        }
}

Así es como podemos incorporarlo fácilmente a nuestra aplicación de Android. Analicemos ahora la conversión de SharedPreferences a Preferencias de DataStore.

4. Transferencia de Preferencias Compartidas a Preferencias de DataStore

Cuando se trata de migración, DataStore se encarga de todo. Solo necesitamos proporcionar los nombres de SharedPreferences. Por ejemplo, si el nombre de SharedPreferences es “gfg-prefs”, debemos realizar lo siguiente:

Kotlin

val sampleDataStore: DataStore<Prefs> =
    context.createDataStore(
        name = "gfg-prefs",
        migrations = listOf(SharedPreferencesMigration(context, "gfg-prefs"))
    )

Conclusión

Podemos ver que hay otras alternativas disponibles, que podemos emplear en función de nuestros casos de uso. La migración de SharedPreferences a DataStore Preferences se hace mucho más fácil de esta manera. SharedPreferences tiene numerosas desventajas, incluida la API asíncrona que puede parecer segura para llamar en el subproceso de la interfaz de usuario, ningún método para informar fallas, ninguna API transaccional y más. DataStore es un sustituto de SharedPreferences que aborda la mayoría de estos problemas. DataStore ofrece una API completamente asíncrona creada con corrutinas de Kotlin y Flow que administra la migración de datos, la consistencia de los datos y la corrupción de datos.

Publicación traducida automáticamente

Artículo escrito por icloudanshu y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *