IO — Ivan Labs

Room vs SharedPreferences vs DataStore: quale storage per cosa

3 min di lettura
Android

Questi tre vengono confrontati come se ne scegliessi uno per l'intera app. In pratica, risolvono problemi diversi e spesso coesistono.

SharedPreferences: il vecchio default, in fase di eliminazione

Storage semplice chiave-valore, storicamente il default per piccole impostazioni. Limitazioni note: è facile usarlo male con letture sincrone sul thread principale (causando jank), non offre sicurezza di tipo a tempo di compilazione, e Google ora raccomanda DataStore come suo sostituto per il nuovo codice.

DataStore: il sostituto moderno per dati semplici chiave-valore

DataStore viene in due varianti — Preferences DataStore (forma simile a SharedPreferences ma asincrona e più sicura) e Proto DataStore (completamente tipizzato, usando protocol buffer). In entrambi i casi, è costruito per lo stesso compito che faceva SharedPreferences — semplici impostazioni e flag — fatto correttamente: asincrono di default, con un modello di consistenza dei dati definito.

val Context.dataStore by preferencesDataStore(name = "settings")
 
val THEME_KEY = stringPreferencesKey("theme")
 
suspend fun saveTheme(context: Context, theme: String) {
    context.dataStore.edit { prefs -> prefs[THEME_KEY] = theme }
}

Room: per dati veramente strutturati e interrogabili

Room è un'astrazione SQLite completa — un layer in stile ORM per dati strutturati con relazioni, query, e (tramite coroutine/Flow) aggiornamenti reattivi. Questo è lo strumento giusto quando hai una collezione genuina di record strutturati: una lista di elementi salvati, risultati API in cache, qualsiasi cosa descriveresti naturalmente come una tabella con righe.

@Entity
data class Note(@PrimaryKey val id: Int, val title: String, val body: String)
 
@Dao
interface NoteDao {
    @Query("SELECT * FROM Note ORDER BY id DESC")
    fun getAll(): Flow<List<Note>>
}

Tabella di confronto

SharedPreferencesDataStoreRoom
Ideale perCodice legacy (evitare per nuovo codice)Impostazioni/flag sempliciDati strutturati, interrogabili
Sicurezza di tipoNessunaForte (specialmente Proto DataStore)Forte
Asincrono di defaultNo (fonte comune di bug)Sì (con coroutine/Flow)
Gestisce relazioni/queryNoNo
Raccomandazione attuale di GoogleIn fase di eliminazioneSì, per dati chiave-valoreSì, per dati strutturati

La regola pratica

Se è una manciata di flag o preferenze (tema, se l'onboarding è stato mostrato, un toggle notifiche), usa DataStore. Se è una collezione genuina di record strutturati che interrogheresti, filtreresti, o metteresti in relazione con altri dati, usa Room. Evita di iniziare nuovo codice con SharedPreferences — il costo di migrazione a DataStore in seguito è evitabile iniziando direttamente lì.

Questa decisione si collega direttamente alla domanda architetturale più ampia — vedi la nostra guida su progettare l'architettura Android per evitare riscritture per come le scelte del layer dati si inseriscono nel quadro più ampio.

Domande frequenti

SharedPreferences è deprecato?

Non formalmente rimosso, ma Google raccomanda DataStore come sostituto per il nuovo codice — SharedPreferences ha problemi noti (API sincrona sul thread principale, nessuna tipizzazione forte) che DataStore è stato costruito specificamente per affrontare.

Posso usare più di uno di questi nella stessa app?

Sì, ed è comune — Room per dati strutturati (una lista di elementi, record utente), DataStore per semplici impostazioni e preferenze dell'app, usati insieme piuttosto che come scelte concorrenti per lo stesso compito.

Ho bisogno di Room per una semplice schermata di impostazioni?

No — Room è costruito per dati strutturati e interrogabili con relazioni. Una manciata di preferenze utente (scelta del tema, toggle notifiche) è esattamente ciò per cui DataStore è progettato invece.

Hai bisogno di aiuto con questo?

Contattami e ti aiuterò a risolvere.

Contattami

Articoli correlati

Condividi:X / TwitterLinkedIn