Saltar a contenido

8.4 Datos locales: DataStore y Room

Necesito guardar… Usa
Un ajuste sencillo (modo oscuro, nombre de usuario) DataStore
Datos estructurados (tareas, contactos…) que se consultan Room (base de datos SQLite)

DataStore: preferencias

implementation("androidx.datastore:datastore-preferences:1.1.1")
val Context.datos by preferencesDataStore("ajustes")
val CLAVE_OSCURO = booleanPreferencesKey("oscuro")

// Leer: es un Flow, se actualiza solo
val oscuro: Flow<Boolean> = contexto.datos.data.map { it[CLAVE_OSCURO] ?: false }

// Escribir (función suspendida)
suspend fun guardar(valor: Boolean) = contexto.datos.edit { it[CLAVE_OSCURO] = valor }

Room: base de datos

Dependencias (Room genera código con el plugin KSP, que hay que añadir en plugins { }):

implementation("androidx.room:room-runtime:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
ksp("androidx.room:room-compiler:2.6.1")

Room traduce clases Kotlin a tablas SQL. Tiene tres piezas:

Entidad (una tabla):

@Entity(tableName = "tareas")
data class Tarea(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val titulo: String,
    val hecha: Boolean = false
)

DAO (las consultas):

@Dao
interface TareaDao {
    @Query("SELECT * FROM tareas ORDER BY id DESC")
    fun todas(): Flow<List<Tarea>>

    @Insert
    suspend fun insertar(t: Tarea)

    @Update
    suspend fun actualizar(t: Tarea)

    @Delete
    suspend fun borrar(t: Tarea)
}

Base de datos:

@Database(entities = [Tarea::class], version = 1)
abstract class AppDb : RoomDatabase() {
    abstract fun tareaDao(): TareaDao
}

val db = Room.databaseBuilder(contexto, AppDb::class.java, "tareas.db").build()

Como todas() devuelve un Flow, la lista de la pantalla se actualiza sola cada vez que insertas o borras. Esa es la gran ventaja: el ViewModel observa la base de datos y la interfaz solo dibuja.

Un paso más

Las migraciones (cambiar la estructura al actualizar la app) y las relaciones entre tablas son temas de acceso a datos que se verán con más detalle en el módulo correspondiente.