Salvare i dati in un database locale utilizzando Room Componente di Android Jetpack.
Le app che gestiscono quantità non trascurabili di dati strutturati possono trarre grandi vantaggi dalla memorizzazione locale di questi dati. Il caso d'uso più comune è memorizzare nella cache frammenti di dati pertinenti in modo che, quando il dispositivo non può accedere alla rete, l'utente possa comunque sfogliare i contenuti offline.
La libreria di persistenza Room fornisce un livello di astrazione su SQLite per consentire un accesso fluido al database sfruttando al contempo tutta la potenza di SQLite. In particolare, Room offre i seguenti vantaggi:
- Verifica in fase di compilazione delle query SQL.
- Annotazioni di praticità che riducono al minimo il codice boilerplate ripetitivo e soggetto a errori.
- Percorsi di migrazione del database semplificati.
Per questi motivi, ti consigliamo vivamente di utilizzare Room anziché utilizzare direttamente le API SQLite.
Configura
Per utilizzare Room nella tua app, aggiungi le seguenti dipendenze al file build.gradle
dell'app.
Kotlin
dependencies { val room_version = "2.6.1" implementation("androidx.room:room-runtime:$room_version") // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP) // See Add the KSP plugin to your project ksp("androidx.room:room-compiler:$room_version") // If this project only uses Java source, use the Java annotationProcessor // No additional plugins are necessary annotationProcessor("androidx.room:room-compiler:$room_version") // optional - Kotlin Extensions and Coroutines support for Room implementation("androidx.room:room-ktx:$room_version") // optional - RxJava2 support for Room implementation("androidx.room:room-rxjava2:$room_version") // optional - RxJava3 support for Room implementation("androidx.room:room-rxjava3:$room_version") // optional - Guava support for Room, including Optional and ListenableFuture implementation("androidx.room:room-guava:$room_version") // optional - Test helpers testImplementation("androidx.room:room-testing:$room_version") // optional - Paging 3 Integration implementation("androidx.room:room-paging:$room_version") }
Groovy
dependencies { def room_version = "2.6.1" implementation "androidx.room:room-runtime:$room_version" // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP) // See KSP Quickstart to add KSP to your build ksp "androidx.room:room-compiler:$room_version" // If this project only uses Java source, use the Java annotationProcessor // No additional plugins are necessary annotationProcessor "androidx.room:room-compiler:$room_version" // optional - RxJava2 support for Room implementation "androidx.room:room-rxjava2:$room_version" // optional - RxJava3 support for Room implementation "androidx.room:room-rxjava3:$room_version" // optional - Guava support for Room, including Optional and ListenableFuture implementation "androidx.room:room-guava:$room_version" // optional - Test helpers testImplementation "androidx.room:room-testing:$room_version" // optional - Paging 3 Integration implementation "androidx.room:room-paging:$room_version" }
Componenti principali
Room è composto da tre componenti principali:
- La classe database che contiene il database e funge da punto di accesso principale per la connessione sottostante ai dati permanenti della tua app.
- Entità di dati che rappresentano le tabelle nel database della tua app.
- Oggetti di accesso ai dati (DAO) che forniscono metodi che la tua app può utilizzare per eseguire query, aggiornare, inserire ed eliminare i dati nel database.
La classe del database fornisce all'app istanze delle DAO associate a quel database. A sua volta, l'app può utilizzare i DAO per recuperare i dati dal database come istanze degli oggetti entità di dati associati. L'app può anche utilizzare le entità di dati definite per aggiornare le righe delle tabelle corrispondenti o per creare nuove righe per l'inserimento. La Figura 1 illustra la relazione tra i diversi componenti di Room.
Esempio di implementazione
Questa sezione presenta un esempio di implementazione di un database Room con una singola entità di dati e un singolo DAO.
Entità dati
Il codice seguente definisce un'entità di dati User
. Ogni istanza di User
rappresenta una riga in una tabella user
nel database dell'app.
Kotlin
@Entity data class User( @PrimaryKey val uid: Int, @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
Java
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
Per scoprire di più sulle entità di dati in Room, consulta la sezione Definire i dati utilizzando le entità Room.
Oggetto di accesso ai dati (DAO)
Il codice seguente definisce un DAO chiamato UserDao
. UserDao
fornisce i metodi utilizzati dal resto dell'app per interagire con i dati nella tabella user
.
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user") fun getAll(): List<User> @Query("SELECT * FROM user WHERE uid IN (:userIds)") fun loadAllByIds(userIds: IntArray): List<User> @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") fun findByName(first: String, last: String): User @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void delete(User user); }
Per scoprire di più sulle DAO, consulta Accedere ai dati utilizzando le DAO di Room.
Database
Il codice seguente definisce una classe AppDatabase
per contenere il database.
AppDatabase
definisce la configurazione del database e funge da punto di accesso principale dell'app ai dati persistenti. La classe del database deve soddisfare le seguenti condizioni:
- La classe deve essere annotata con un'annotazione
@Database
che include un arrayentities
che elenca tutte le entità di dati associate al database. - La classe deve essere una classe astratta che estende
RoomDatabase
. - Per ogni classe DAO associata al database, la classe del database deve definire un metodo astratto senza argomenti che restituisce un'istanza della classe DAO.
Kotlin
@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
Java
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
Nota: se la tua app viene eseguita in un'unica operazione, devi seguire il pattern di progettazione singleton quando esegui l'inizializzazione di un oggetto AppDatabase
. Ogni istanza RoomDatabase
è piuttosto costosa e raramente è necessario accedere a più istanze all'interno di un'unica operazione.
Se la tua app viene eseguita in più processi, includi
enableMultiInstanceInvalidation()
nell'invocazione del generatore di database. In questo modo, quando hai un'istanza di AppDatabase
in ogni processo, puoi invalidare il file del database condiviso in un processo,
e questa invalidazione si propaga automaticamente alle istanze di
AppDatabase
all'interno di altri processi.
Utilizzo
Dopo aver definito l'entità di dati, il DAO e l'oggetto database, puoi utilizzare il seguente codice per creare un'istanza del database:
Kotlin
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
Java
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
Puoi quindi utilizzare i metodi astratti di AppDatabase
per ottenere un'istanza del DAO. A tua volta, puoi utilizzare i metodi dell'istanza DAO per interagire con il database:
Kotlin
val userDao = db.userDao() val users: List<User> = userDao.getAll()
Java
UserDao userDao = db.userDao(); List<User> users = userDao.getAll();
Risorse aggiuntive
Per scoprire di più su Room, consulta le seguenti risorse aggiuntive: