Per evitare che le query blocchino la UI, la stanza virtuale non consente l'accesso al database su nel thread principale. Questa limitazione significa che devi rendere asincrone le query DAO. La libreria Room include integrazioni con diversi framework per fornire l'esecuzione di query asincrone.
Le query DAO rientrano in tre categorie:
- Query di scrittura one-shot che inseriscono, aggiornano o eliminano dati nel database.
- Query di lettura one-shot che leggono i dati dal database una sola volta e restituiscono un risultato con lo snapshot del database in quel momento.
- Query di lettura osservabile che leggono i dati dal database ogni volta le tabelle di database sottostanti cambiano ed emettono nuovi valori per riflettere quelli modifiche.
Opzioni di linguaggio e framework
La stanza virtuale fornisce il supporto per l'integrazione per l'interoperabilità con un linguaggio specifico funzionalità e librerie. La tabella seguente mostra i tipi di reso applicabili in base sul tipo di query e sul framework:
Tipo di query | Funzionalità del linguaggio Kotlin | RxJava | Guava | Jetpack Lifecycle |
---|---|---|---|---|
Scrittura one-shot | Coroutine (suspend ) |
Single<T> , Maybe<T> ,
Completable |
ListenableFuture<T> |
N/D |
Lettura one-shot | Coroutine (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
N/D |
Lettura osservabile | Flow<T> |
Flowable<T> , Publisher<T> ,
Observable<T> |
N/D | LiveData<T> |
Questa guida illustra tre possibili modi per utilizzare queste integrazioni per implementare query asincrone nei DAO.
Kotlin con Flow e couroutine
Kotlin offre funzionalità linguistiche che ti consentono di scrivere query asincrone senza framework di terze parti:
- Nella stanza 2.2 e successive, puoi usare Flusso per scrivere query osservabili.
- Nella stanza 2.1 e successive, puoi utilizzare la parola chiave
suspend
per rendere il tuo DAO le query in modo asincrono utilizzando le coroutine di Kotlin.
Java con RxJava
Se la tua app utilizza il linguaggio di programmazione Java, puoi utilizzare caratteri di ritorno specializzati del framework RxJava per scrivere metodi DAO asincroni. Le camere offrono supporto per i seguenti tipi restituiti RxJava 2:
- Per le query one-shot, la stanza 2.1 e le versioni successive supporta
Completable
,Single<T>
, eMaybe<T>
i tipi restituiti. - Per le query osservabili, Room supporta
Publisher<T>
,Flowable<T>
, eObservable<T>
i tipi restituiti.
Inoltre, Room 2.3 e versioni successive supportano RxJava 3.
Java con LiveData e Guava
Se la tua app utilizza il linguaggio di programmazione Java e non desideri utilizzare RxJava, puoi utilizzare le seguenti alternative per scrivere query:
- Puoi utilizzare la classe wrapper
LiveData
di Jetpack per scrivere query osservabili asincrone. - Puoi utilizzare lo
ListenableFuture<T>
un wrapper per la scrittura di query one-shot asincrone.
Scrivere query one-shot asincrone
Le query one-shot sono operazioni di database che vengono eseguite una sola volta e acquisiscono uno snapshot di dati al momento dell'esecuzione. Di seguito sono riportati alcuni esempi di modelli query one-shot:
Kotlin
@Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertUsers(vararg users: User) @Update suspend fun updateUsers(vararg users: User) @Delete suspend fun deleteUsers(vararg users: User) @Query("SELECT * FROM user WHERE id = :id") suspend fun loadUserById(id: Int): User @Query("SELECT * from user WHERE region IN (:regions)") suspend fun loadUsersByRegion(regions: List<String>): List<User> }
Java
@Dao public interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) public Completable insertUsers(List<User> users); @Update public Completable updateUsers(List<User> users); @Delete public Completable deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public Single<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Single<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { // Returns the number of users inserted. @Insert(onConflict = OnConflictStrategy.REPLACE) public ListenableFuture<Integer> insertUsers(List<User> users); // Returns the number of users updated. @Update public ListenableFuture<Integer> updateUsers(List<User> users); // Returns the number of users deleted. @Delete public ListenableFuture<Integer> deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public ListenableFuture<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public ListenableFuture<List<User>> loadUsersByRegion(List<String> regions); }
Scrivere query osservabili
Le query osservabili sono operazioni di lettura che emettono nuovi valori ogni volta che modifiche a qualsiasi tabella a cui fa riferimento la query. Un modo per utilizzarlo è mantenere aggiornato un elenco visualizzato di elementi man mano che gli elementi nel database sottostante vengono inseriti, aggiornati o rimossi. Ecco alcuni esempi esempi di query osservabili:
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") fun loadUserById(id: Int): Flow<User> @Query("SELECT * from user WHERE region IN (:regions)") fun loadUsersByRegion(regions: List<String>): Flow<List<User>> }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public Flowable<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Flowable<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public LiveData<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public LiveData<List<User>> loadUsersByRegion(List<String> regions); }
Risorse aggiuntive
Per ulteriori informazioni sulle query DAO asincrone, consulta anche di risorse: