Room 3.0
| Ultimo aggiornamento | Release stabile | Candidato per la release | Release beta | Release alpha |
|---|---|---|---|---|
| 11 marzo 2026 | - | - | - | 3.0.0-alpha01 |
Dichiara le dipendenze
Per aggiungere una dipendenza da Room3, devi aggiungere il repository Maven di Google al tuo progetto. Per saperne di più, consulta il repository Maven di Google.
Aggiungi le dipendenze per gli artefatti necessari nel file build.gradle per
la tua app o il tuo modulo:
Kotlin
dependencies { val room_version = "" implementation("androidx.room3:room3-runtime:$room_version") ksp("androidx.room3:room3-compiler:$room_version") }
Groovy
dependencies { def room_version = "" implementation "androidx.room3:room3-runtime:$room_version" ksp "androidx.room3:room3-compiler:$room_version" }
Per informazioni sull'utilizzo del plug-in KSP, consulta la documentazione di avvio rapido di KSP.
Per saperne di più sulle dipendenze, consulta Aggiungere dipendenze di build.
Utilizzare il plug-in Gradle di Room
Puoi utilizzare il plug-in Gradle di Room per configurare le opzioni per il compilatore Room. Il plug-in configura il progetto in modo che gli schemi generati (che sono un output delle attività di compilazione e vengono utilizzati per le migrazioni automatiche) siano configurati correttamente per avere build riproducibili e memorizzabili nella cache.
Per aggiungere il plug-in, definisci il plug-in e la relativa versione nel file di build Gradle di primo livello.
Groovy
plugins { id 'androidx.room3' version "$room_version" apply false }
Kotlin
plugins { id("androidx.room3") version "$room_version" apply false }
Nel file di build Gradle a livello di modulo, applica il plug-in e utilizza l'estensione room3.
Groovy
plugins { id 'androidx.room3' } room3 { schemaDirectory "$projectDir/schemas" }
Kotlin
plugins { id("androidx.room3") } room3 { schemaDirectory("$projectDir/schemas") }
L'impostazione di un schemaDirectory è obbligatoria quando utilizzi il plug-in Gradle Room. In questo modo
verranno configurati il compilatore Room e le varie attività di compilazione e i relativi backend
(kotlinc, KSP) per generare file di schema in cartelle con varianti, ad esempio
schemas/flavorOneDebug/com.package.MyDatabase/1.json. Questi file devono essere
inseriti nel repository per essere utilizzati per la convalida e le migrazioni automatiche.
Feedback
Il tuo feedback ci aiuta a migliorare Jetpack. Facci sapere se riscontri nuovi problemi o hai idee per migliorare questa raccolta. Prima di segnalare un nuovo problema, dai un'occhiata ai problemi esistenti in questa raccolta. Puoi aggiungere il tuo voto a un problema esistente facendo clic sul pulsante a forma di stella.
Per saperne di più, consulta la documentazione di Issue Tracker.
Versione 3.0
Versione 3.0.0-alpha01
11 marzo 2026
androidx.room3:room3-*:3.0.0-alpha01 è stato rilasciato.
Room 3.0 (pacchetto androidx.room3) è un aggiornamento della versione principale del pacchetto Room 2.x (androidx.room) incentrato su Kotlin Multiplatform (KMP).
Le API di annotazione principali vengono mantenute invariate, così come i componenti principali:
- Una classe astratta che estende
androidx.room3.RoomDatabasee che è annotata con@Databaseè il punto di ingresso per il processore di annotazioni di Room. - La dichiarazione del database contiene una o più classi di dati che descrivono lo schema del database e sono annotate con
@Entity. - Le operazioni del database sono definite nelle dichiarazioni
@Daoche contengono funzioni di query le cui istruzioni SQL sono definite tramite l'annotazione@Query. - In fase di runtime, l'implementazione del database può essere ottenuta tramite un
RoomDatabase.Builder, che viene utilizzato anche per configurare il database.
La maggior parte della documentazione della guida Salvare i dati in un database locale utilizzando Room è ancora pertinente a Room 3.0.
Le principali differenze sostanziali tra Room 2.x sono le seguenti:
- Nuovo pacchetto,
androidx.room3. - Le API SupportSQLite non sono più supportate, a meno che tu non utilizzi
androidx.room3:room3-sqlite-wrapper. - Tutte le operazioni del database ora si basano sulle API Coroutine.
- Solo generazione di codice Kotlin.
- È necessario Kotlin Symbol Processing (KSP).
Oltre alle modifiche che causano interruzioni, Room 3.0 introduce nuove funzionalità rispetto alla versione 2.x:
- Supporto di JS e WasmJS
- Tipi di ritorno DAO personalizzati
Nuovo pacchetto
Per evitare problemi di compatibilità con le implementazioni Room 2.x esistenti e per
le librerie con dipendenze transitive da Room (ad esempio WorkManager),
Room 3.0 si trova in un nuovo pacchetto, il che significa che ha anche un nuovo gruppo Maven e
nuovi ID artefatto. Ad esempio, androidx.room:room-runtime è diventato
androidx.room3:room3-runtime e le classi come androidx.room.RoomDatabase
ora si trovano all'indirizzo androidx.room3.RoomDatabase.
Nessuna API SupportSQLite
Room 3.0 è completamente supportato dalle API SQLiteDriver e non fa più riferimento a tipi SupportSQLite come SupportSQLiteDatabase o a tipi Android come Cursor. Si tratta della modifica più significativa tra
Room 3.0 e 2.x, poiché sono state rimosse le API RoomDatabase che rispecchiavano
SupportSQLiteDatabase, nonché l'API per ottenere un SupportSQLiteOpenHelper. Ora è obbligatorio un SQLiteDriver per creare un
RoomDatabase.
Ad esempio, le API per le operazioni dirette sul database vengono sostituite dagli equivalenti dei driver:
// Room 2.x
roomDatabase.runInTransaction { ... }
// Room 3.x
roomDatabase.withWriteTransaction { ... }
// Room 2.x
roomDatabase.query("SELECT * FROM Song").use { cursor -> ... }
// Room 3.x
roomDatabase.useReaderConnection { connection ->
connection.usePrepared("SELECT * FROM Song") { stmt -> ... }
}
Anche le API di callback che avevano come argomento un SupportSQLiteDatabase sono state
sostituite dalla rispettiva API equivalente che ha un SQLiteConnection come argomento.
Si tratta di funzioni di callback delle migrazioni come Migration.onMigrate() e
AutoMigrationSpec.onPostMigrate(), nonché di callback del database come
RoomDatabase.Callback.onCreate(), RoomDatabase.Callback.onOpen() e così via.
Se Room veniva utilizzato in un progetto KMP, la migrazione alla versione 3.0 è più semplice, in quanto comporta principalmente l'aggiornamento dei riferimenti di importazione. In caso contrario, si applica la stessa strategia di migrazione da Room solo in Android a KMP. Consulta la guida alla migrazione di Room KMP.
SupportSQLite Wrapper
Room 3.x conserva il wrapper SupportSQLite creato nella versione 2.x per semplificare le migrazioni
e ora si trova in un nuovo artefatto androidx.room3:room3-sqlite-wrapper. L'API
di compatibilità ti consente di convertire un RoomDatabase in un
SupportSQLiteDatabase. Le invocazioni di
roomDatabase.openHelper.writableDatabase possono essere sostituite da
roomDatabase.getSupportWrapper().
Kotlin e coroutine prima di tutto
Per migliorare l'evoluzione della libreria, Room 3.0 genera solo codice Kotlin ed è solo un processore di simboli Kotlin (KSP). Rispetto a Room 2.x, non è più possibile generare codice Java e configurare il processore di annotazioni tramite KAPT o JavaAP in Room 3.0. Tieni presente che KSP è in grado di elaborare le origini Java e il compilatore Room genererà codice per database, entità o DAO le cui dichiarazioni di origine sono in Java. È consigliabile avere un progetto multimodulo in cui l'utilizzo di Room è concentrato e il plug-in Gradle per Kotlin e KSP possono essere applicati senza influire sul resto del codebase.
Room 3.0 richiede anche l'uso di coroutine e, più nello specifico, le funzioni DAO devono essere sospese a meno che non restituiscano un tipo reattivo, ad esempio un Flow o un tipo restituito DAO personalizzato. Le API Room per eseguire operazioni
sul database sono anche funzioni di sospensione, come
RoomDatabase.useReaderConnection e RoomDatabase.useWriterConnection.
A differenza di Room 2.x, non è più possibile configurare un RoomDatabase
con un Executor. In alternativa, è possibile fornire un CoroutineContext insieme a un dispatcher
tramite il builder del database.
Le API InvalidationTracker in Room 3.0 sono basate su Flow,
InvalidationTracker.Observer viene rimosso insieme alle relative API
addObserver e removeObserver. Il meccanismo per reagire all'operazione del database
avviene tramite i flussi di coroutine che possono essere creati tramite l'API createFlow() in
InvalidationTracker.
Esempio di utilizzo:
fun getArtistTours(from: Date, to: Date): Flow<Map<Artist, TourState>> {
return db.invalidationTracker.createFlow("Artist").map { _ ->
val artists = artistsDao.getAllArtists()
val tours = tourService.fetchStates(artists.map { it.id })
associateTours(artists, tours, from, to)
}
}
Supporto web
La release 3.0 di Room aggiunge JavaScript e WasmJs come target KMP. Insieme al rilascio delle interfacce SQLiteDriver (androidx.sqlite:sqlite) che hanno come target anche JavaScript e WasmJs e di un nuovo driver WebWorkerSQLiteDriver che si trova nel nuovo artefatto androidx.sqlite:sqlite-web, è possibile utilizzare Room nel codice comune che ha come target tutte le principali piattaforme KMP.
A causa della natura asincrona delle piattaforme web, le API Room che prendevano
SQLiteStatement come argomento sono ora funzioni di sospensione. Esempi di queste
funzioni sono Migration.onMigrate(), RoomDatabase.Callback.onCreate(),
PooledConnection.usePrepared() e altre. Nelle API del driver, le API asincrone sono comuni a tutte le piattaforme e quelle sincrone sono comuni
per le destinazioni non web. Pertanto, un progetto che non ha come target il web può continuare
a utilizzare le API sincrone (SQLiteDriver.open(),
SQLiteConnection.prepare() e SQLiteStatement.step()) nel codice comune.
Nel frattempo, un progetto che ha come target solo il web deve utilizzare le API asincrone
(SQLiteDriver.openAsync(), SQLiteConnection.prepareAsync() e
SQLiteStatement.stepAsync()).
Per comodità, il pacchetto androidx.sqlite ha aggiunto anche funzioni di estensione della sospensione con i nomi sincroni delle API menzionate (con l'aggiunta di SQLiteConnection.executeSQL). Queste API sono consigliate quando il progetto ha come target piattaforme web e non web, poiché sono dichiarazioni di attesa / effettive che chiameranno la variante corretta in base alle piattaforme. Queste sono
le API utilizzate dal runtime di Room e consentono l'utilizzo dei driver nel codice comune per tutte le
piattaforme supportate.
Esempio di utilizzo:
import androidx.sqlite.executeSQL
import androidx.sqlite.step
roomDatabase.useWriterConnection { connection ->
val deletedSongs = connection.usePrepared(
"SELECT count(*) FROM Song"
) { stmt ->
stmt.step()
stmt.getLong(0)
}
connection.executeSQL("DELETE FROM Song")
deletedSongs
}
WebWorkerSQLiteDriver è un'implementazione di un SQLiteDriver che
comunica con un Web Worker
per eseguire l'operazione di database al di fuori del thread principale e consente di archiviare il
database in Origin Private File System (OPFS). Per creare un'istanza del driver
è necessario un worker che implementi un semplice protocollo di comunicazione. Il
protocollo è descritto in WebWorkerSQLiteDriver
KDoc.
Al momento, WebWorkerSQLiteDriver non viene fornito con un worker predefinito che implementa il protocollo di comunicazione, ma, ad esempio, il codebase androidx contiene un'implementazione
del worker
che può essere utilizzata nel tuo progetto. Utilizza WASM di SQLite e archivia il database in OPFS. Il worker di esempio viene pubblicato come pacchetto NPM locale e, grazie al
supporto di Kotlin per le dipendenze NPM,
è possibile creare un piccolo modulo KMP per pubblicare il worker.
Consulta il seguente progetto GitHub che mostra l'utilizzo di un web worker locale per Room.
Una volta configurato un lavoratore nel progetto, la configurazione di Room for the Web è simile a quella di altre piattaforme:
fun createDatabase(): MusicDatabase {
return Room.databaseBuilder<MusicDatabase>("music.db")
.setDriver(WebWorkerSQLiteDriver(createWorker()))
.build()
}
fun createWorker() =
Worker(js("""new URL("sqlite-web-worker/worker.js", import.meta.url)"""))
Una versione futura del driver web potrebbe contenere un worker predefinito pubblicato in NPM, semplificando la configurazione web.
Tipi di ritorno DAO personalizzati
Varie integrazioni di tipi restituiti DAO, come quelle per RxJava e Paging, sono state trasformate per utilizzare una nuova API in Room 3.0 chiamata convertitori di tipi restituiti DAO.
Una funzione di conversione del tipo restituito DAO (@DaoReturnTypeConverter) consente di trasformare il risultato di una funzione DAO in un tipo personalizzato definito dalla funzione annotata. Queste funzioni consentono di partecipare al codice generato da Room che trasforma i risultati delle query in oggetti dati. Le classi che contengono
convertitori di tipi restituiti DAO devono essere registrate tramite le
annotazioni @DaoReturnTypeConverters nelle dichiarazioni @Database o @Dao.
Ad esempio, per fare in modo che una query DAO restituisca un PagingSource, ora deve essere registrata la classe del convertitore
che si trova in androidx.room3:room3-paging:
@Dao
@DaoReturnTypeConverters(PagingSourceDaoReturnTypeConverter::class)
interface MusicDao {
@Query("SELECT * FROM Song)
fun getSongsPaginated(): PagingSource<Int, Song>
}
Le integrazioni esistenti sono state spostate nei convertitori di tipi restituiti DAO:
| Tipo restituito | Classe di conversione | Elemento |
|---|---|---|
| PagingSource | PagingSourceDaoReturnTypeConverter | androidx.room3:room3-paging |
| Observable, Flowable, Completable, Single, Maybe | RxDaoReturnTypeConverters | androidx.room3:room3-rxjava3 |
| ListenableFuture | GuavaDaoReturnTypeConverter | androidx.room3:room3-guava |
| LiveData | LiveDataDaoReturnTypeConverter | androidx.room3:room3-livedata |
Come i convertitori di tipi di colonne, i convertitori di tipi restituiti DAO possono essere definiti dall'applicazione. Ad esempio, un'applicazione potrebbe dichiarare un
@DaoReturnTypeConverter per il tipo web kotlin.js.Promise.
object PromiseDaoReturnTypeConverter {
@DaoReturnTypeConverter([OperationType.READ, OperationType.WRITE])
fun <T> convert(
db: RoomDatabase,
executeAndConvert: suspend () -> T
): Promise<T> {
return db.getCoroutineScope().promise { executeAndConvert() }
}
}
Il convertitore precedente consente quindi alle funzioni di query DAO di restituire Promise:
@Dao
@DaoReturnTypeConverters(PromiseDaoReturnTypeConverter::class)
interface MusicDao {
@Query("SELECT * FROM Song")
fun getAllSongs(): Promise<List<Song>>
}
Una funzione @DaoReturnTypeConverter ha alcuni requisiti in termini di quantità di parametri che deve avere e dei relativi tipi. I parametri possibili sono:
db: RoomDatabase: (facoltativo) fornisce l'accesso all'istanzaRoomDatabase, che può essere utile per eseguire operazioni aggiuntive sul database o accedere all'ambito della coroutine.tableNames: Array<String>: (facoltativo) contiene le tabelle a cui è stato eseguito l'accesso della query, utile per supportare i tipi osservabili / reattivi se combinato con l'APIInvalidationTracker.createFlow()di Room.rawQuery: RoomRawQuery: (facoltativo) contiene al runtime un'istanza della query, consentendo trasformazioni come la strategiaLIMIT/OFFSETimplementata daPagingSourceDaoReturnTypeConverter.executeAndConvert: suspend () -> T: (obbligatorio) la funzione Room generata che eseguirà la query e analizzerà il risultato in oggetti dati.
Per saperne di più sui requisiti per la creazione di un convertitore del tipo restituito DAO, consulta il KDoc sull'API @DaoReturnTypeConverter.