DataStore Preferences
Reemplace SharedPreferences por la biblioteca moderna DataStore. Lea datos como un Kotlin Flow, escríbalos con edit{} y gestione los errores de forma segura.
DataStore Preferences es una lección gratuita de Android Academy en CoddyKit. Esta es la lección 5 de 6. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Android Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Android Academy incluye 6 lecciones en total.
¿Por qué DataStore?
DataStore es el sustituto moderno de SharedPreferences. Resuelve problemas reales:
- SharedPreferences bloquea el hilo de la interfaz de usuario; DataStore es completamente asíncrono
- SharedPreferences puede producir excepciones no controladas; DataStore gestiona los errores mediante Flow
- DataStore ofrece seguridad de tipos (Preferences) o seguridad de esquema (Proto)
- Funciona de forma nativa con Kotlin Coroutines y Flow
Dos tipos de DataStore
Elija el tipo adecuado para su caso de uso:
- Preferences DataStore — pares clave-valor, sin necesidad de esquema. Es el más sencillo de configurar. Ideal para ajustes de la aplicación y preferencias del usuario.
- Proto DataStore — objetos tipados mediante Protocol Buffers. Requiere un archivo de esquema .proto. Ideal cuando se trabaja con datos estructurados.
Esta lección trata sobre Preferences DataStore.
Añadir la dependencia
Añada DataStore a app/build.gradle:
// app/build.gradle
dependencies {
implementation 'androidx.datastore:datastore-preferences:1.1.1'
// Coroutines (likely already in your project)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}Crear una instancia de DataStore
Cree DataStore una sola vez mediante el delegado de nivel superior. Normalmente, esto se hace en un archivo independiente:
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
// Top-level property — creates a single DataStore instance per Context
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")Definir las claves
Las claves son objetos con seguridad de tipos, no simples cadenas. Créelas con la función de fábrica adecuada:
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
object PreferencesKeys {
val DARK_MODE = booleanPreferencesKey("dark_mode")
val USER_NAME = stringPreferencesKey("user_name")
val LAUNCH_COUNT = intPreferencesKey("launch_count")
}Escribir datos
Escriba dentro de una corrutina mediante edit { }:
import androidx.datastore.preferences.core.edit
// In a ViewModel or Repository:
suspend fun saveDarkMode(enabled: Boolean) {
context.dataStore.edit { prefs ->
prefs[PreferencesKeys.DARK_MODE] = enabled
}
}
suspend fun incrementLaunchCount() {
context.dataStore.edit { prefs ->
val current = prefs[PreferencesKeys.LAUNCH_COUNT] ?: 0
prefs[PreferencesKeys.LAUNCH_COUNT] = current + 1
}
}Leer datos con Flow
DataStore expone los datos como un Flow. Use map para extraer el valor que necesita:
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
val darkModeFlow: Flow<Boolean> = context.dataStore.data
.map { prefs ->
prefs[PreferencesKeys.DARK_MODE] ?: false // default = false
}
val userNameFlow: Flow<String> = context.dataStore.data
.map { prefs ->
prefs[PreferencesKeys.USER_NAME] ?: "Guest"
}Recopilar datos en ViewModel
Exponga los Flow de DataStore desde un ViewModel mediante stateIn para recopilarlos de forma eficiente:
class SettingsViewModel(private val repo: SettingsRepository) : ViewModel() {
val isDarkMode: StateFlow<Boolean> = repo.darkModeFlow
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = false
)
fun toggleDarkMode(enabled: Boolean) {
viewModelScope.launch {
repo.saveDarkMode(enabled)
}
}
}Observar en Activity/Fragment
Recopile el StateFlow en la interfaz de usuario mediante lifecycleScope.launch:
// In Fragment:
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.isDarkMode.collect { darkMode ->
binding.switchDarkMode.isChecked = darkMode
AppCompatDelegate.setDefaultNightMode(
if (darkMode) AppCompatDelegate.MODE_NIGHT_YES
else AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
)
}
}
}Gestión de errores
DataStore emite IOException si el archivo está dañado. Captúrela en su canalización de Flow:
import kotlinx.coroutines.flow.catch
import java.io.IOException
val safeFlow: Flow<Boolean> = context.dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences()) // return defaults
} else {
throw exception
}
}
.map { prefs ->
prefs[PreferencesKeys.DARK_MODE] ?: false
}DataStore frente a SharedPreferences
Resumen de las razones por las que DataStore es superior:
- DataStore lee y escribe automáticamente en un hilo en segundo plano — no hay riesgo de ANR
apply()de SharedPreferences puede fallar silenciosamente; DataStore propaga los errores mediante Flow- DataStore es reactivo: la interfaz de usuario se actualiza automáticamente cuando cambian los datos
- SharedPreferences no ofrece una ruta de migración; DataStore incluye
SharedPreferencesMigration
Comprobación rápida
¿Cuál es el mecanismo principal que utiliza DataStore para exponer sus datos al resto de la aplicación?
Repaso: DataStore Preferences
DataStore es la forma moderna de conservar datos sencillos:
- Añada la dependencia
datastore-preferences - Cree una única instancia con el delegado
preferencesDataStore - Defina claves con seguridad de tipos mediante
stringPreferencesKey,booleanPreferencesKey, etc. - Escriba con
dataStore.edit { }dentro de una corrutina - Lea los datos como un
FlowcondataStore.data.map { } - Gestione
IOExceptioncon.catch { emit(emptyPreferences()) }
A continuación: cree adaptadores de listas eficientes con DiffUtil.
Preguntas frecuentes
¿La lección «DataStore Preferences» es gratis?
Sí — el texto completo de «DataStore Preferences» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Android Academy, actualiza a CoddyKit PRO. El curso de Android Academy incluye 6 lecciones en total.
¿Qué aprenderé en «DataStore Preferences»?
Reemplace SharedPreferences por la biblioteca moderna DataStore. Lea datos como un Kotlin Flow, escríbalos con edit{} y gestione los errores de forma segura. Practicas Android Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Android Academy?
No se requiere experiencia previa. Android Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 5 de 6.
¿Cuánto tiempo toma la lección «DataStore Preferences»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Android Academy?
Sí. Cada lección de Android Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Colecciones de Kotlin
- Fundamentos de RecyclerView
- Eventos de clic de RecyclerView
- SharedPreferences
- DataStore Preferences
- Adaptadores y DiffUtil