0Pricing
Android Academy · Lezione

DataStore Preferences

Sostituisca SharedPreferences con la moderna libreria DataStore. Legga i dati come Kotlin Flow, li scriva con edit{} e gestisca gli errori in modo sicuro.

DataStore Preferences è una lezione Android Academy gratuita su CoddyKit. Questa è la lezione 5 di 6. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Android Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Android Academy include 6 lezioni in totale.

Perché DataStore?

DataStore è il sostituto moderno di SharedPreferences. Risolve problemi concreti:

  • SharedPreferences blocca il thread dell'interfaccia utente, mentre DataStore è completamente asincrono
  • SharedPreferences può generare eccezioni non gestite, mentre DataStore gestisce gli errori tramite Flow
  • DataStore offre sicurezza dei tipi (Preferences) o sicurezza dello schema (Proto)
  • Funziona nativamente con Kotlin Coroutines e Flow

Due tipi di DataStore

Scelga il tipo più adatto al proprio caso d'uso:

  • Preferences DataStore — coppie chiave-valore, senza bisogno di uno schema. È il più semplice da configurare. Ideale per le impostazioni dell'app e le preferenze dell'utente.
  • Proto DataStore — oggetti tipizzati che usano Protocol Buffers. Richiede un file di schema .proto. Ideale quando si hanno dati strutturati.

Questa lezione tratta Preferences DataStore.

Aggiunta della dipendenza

Aggiunga 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'
}

Creazione di un'istanza DataStore

Crei DataStore una sola volta usando il delegate di livello superiore. In genere questa operazione viene eseguita in un file separato:

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")

Definizione delle chiavi

Le chiavi sono oggetti type-safe, non semplici stringhe. Le crei con la funzione factory appropriata:

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")
}

Scrittura dei dati

Scriva all'interno di una coroutine usando 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
    }
}

Lettura dei dati con Flow

DataStore espone i dati come Flow. Usi map per estrarre il valore necessario:

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"
    }

Raccolta nel ViewModel

Esponga i Flow di DataStore da un ViewModel usando stateIn per una raccolta efficiente:

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)
        }
    }
}

Osservazione in Activity/Fragment

Raccolga lo StateFlow nell'interfaccia utente usando 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
            )
        }
    }
}

Gestione degli errori

DataStore emette IOException se il file è danneggiato. Intercetti l'eccezione nella pipeline del 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 e SharedPreferences

Riepilogo dei motivi per cui DataStore è la scelta migliore:

  • DataStore legge e scrive automaticamente in un thread in background — nessun rischio di ANR
  • apply() di SharedPreferences può fallire senza segnalare l'errore; DataStore propaga gli errori tramite Flow
  • DataStore è reattivo: l'interfaccia utente si aggiorna automaticamente quando i dati cambiano
  • SharedPreferences non offre un percorso di migrazione; DataStore include SharedPreferencesMigration

Verifica rapida

Qual è il meccanismo principale che DataStore usa per esporre i propri dati al resto dell'app?

Riepilogo: DataStore Preferences

DataStore è il modo moderno per rendere persistenti dati semplici:

  • Aggiungere la dipendenza datastore-preferences
  • Creare una singola istanza con il delegate preferencesDataStore
  • Definire chiavi type-safe con stringPreferencesKey, booleanPreferencesKey e così via
  • Scrivere con dataStore.edit { } all'interno di una coroutine
  • Leggere come Flow con dataStore.data.map { }
  • Gestire IOException con .catch { emit(emptyPreferences()) }

Prossimo argomento: creare adapter efficienti per le liste con DiffUtil.

Domande Frequenti

La lezione «DataStore Preferences» è gratuita?

Sì — il testo completo di «DataStore Preferences» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Android Academy, passa a CoddyKit PRO. Il corso Android Academy include 6 lezioni in totale.

Cosa imparerò in «DataStore Preferences»?

Sostituisca SharedPreferences con la moderna libreria DataStore. Legga i dati come Kotlin Flow, li scriva con edit{} e gestisca gli errori in modo sicuro. Eserciti Android Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Android Academy?

Non è richiesta alcuna esperienza precedente. Android Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 5 di 6.

Quanto tempo richiede la lezione «DataStore Preferences»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Android Academy?

Sì. Ogni lezione Android Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Collection di Kotlin
  2. Nozioni di base su RecyclerView
  3. Eventi di clic di RecyclerView
  4. SharedPreferences
  5. DataStore Preferences
  6. Adapter e DiffUtil
← Torna a Android Academy