Комната - каталог экспорта схемы не предоставлен обработчику аннотаций, поэтому мы не можем экспортировать схему
Я использую компонентную базу данных Android
Я все настроил, но при компиляции Android Studio выдает мне следующее предупреждение:
Каталог экспорта схемы не предоставляется обработчику аннотаций, поэтому мы не можем экспортировать схему. Вы можете предоставить
room.schemaLocation
аргумент процессора аннотации ИЛИ установите для exportSchema значение false.
Как я понимаю, это место, где будет расположен файл БД
Как это может повлиять на мое приложение? Какова лучшая практика здесь? Должен ли я использовать местоположение по умолчанию (false
значение)?
14 ответов
Согласно документам:
Вы можете установить аргумент процессора аннотаций (room.schemaLocation), чтобы сообщить Room об экспорте схемы в папку. Несмотря на то, что это не является обязательным, рекомендуется иметь историю версий в вашей кодовой базе, и вы должны зафиксировать этот файл в вашей системе контроля версий (но не поставляйте его вместе с приложением!).
Так что если вам не нужно проверять схему и вы хотите избавиться от предупреждения, просто добавьте exportSchema = false
на ваш RoomDatabase
, следующее.
@Database(entities = { YourEntity.class }, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
//...
}
Если вы будете следовать ответу @mikejonesguy ниже, вы будете следовать рекомендациям, упомянутым в документации:). В основном вы получите .json
файл в вашем ../app/schemas/
папка. И это выглядит примерно так:
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "53db508c5248423325bd5393a1c88c03",
"entities": [
{
"tableName": "sms_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` TEXT, `date` INTEGER, `client_id` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER"
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT"
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "INTEGER"
},
{
"fieldPath": "clientId",
"columnName": "client_id",
"affinity": "INTEGER"
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"53db508c5248423325bd5393a1c88c03\")"
]
}
}
Если мое понимание верно, вы будете получать такой файл при каждом обновлении версии базы данных, чтобы вы могли легко следить за историей вашей базы данных.
В build.gradle
файл для модуля приложения, добавьте его в defaultConfig
раздел (под android
раздел). Это запишет схему в schemas
подпапка вашей папки проекта.
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
Как это:
// ...
android {
// ... (compileSdkVersion, buildToolsVersion, etc)
defaultConfig {
// ... (applicationId, miSdkVersion, etc)
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
// ... (buildTypes, compileOptions, etc)
}
// ...
Котлин? Вот так:
android {
// ... (compileSdkVersion, buildToolsVersion, etc)
defaultConfig {
// ... (applicationId, miSdkVersion, etc)
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
}
buildTypes {
// ... (buildTypes, compileOptions, etc)
}
}
//...
Не забудьте о плагине:
apply plugin: 'kotlin-kapt'
Для получения дополнительной информации о процессоре аннотаций kotlin, пожалуйста, посетите: Kotlin docs
Для Котлин КСП:
ksp {
arg('room.schemaLocation', "$projectDir/schemas")
}
Выше ответы верны. Эту версию легко понять:
Поскольку "Каталог экспорта схемы не предоставляется процессору аннотаций", поэтому нам нужно предоставить каталог для экспорта схемы:
Шаг [1] В вашем файле, который расширяет RoomDatabase, измените строку на:
`@Database(entities = ???.class,version = 1, exportSchema = true)`
Или же
`@Database(entities = ???.class,version = 1)`
(потому что значение по умолчанию всегда верно)
Шаг [2] В вашем файле build.gradle(project:????), внутри defaultConfig {} (который находится внутри большого раздела android{ }), добавьте раздел javaCompileOptions{ }, это будет выглядеть так:
android{
defaultConfig{
//javaComplieOptions SECTION
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":"$projectDir/schemas".toString()]
}
}
//Other SECTION
...
}
}
$ projectDir: это имя переменной, вы не можете его изменить. он получит ваш собственный каталог проектов
схемы: это строка, вы можете изменить ее на любую, какую захотите. Например:"$projectDir/MyOwnSchemas".toString()
Ответ @mikejonesguy идеален, на случай, если вы планируете протестировать миграцию комнаты (рекомендуется), добавьте расположение схемы в исходные наборы.
В вашем файле build.gradle вы указываете папку для размещения этих сгенерированных файлов JSON схемы. При обновлении схемы у вас будет несколько файлов JSON, по одному для каждой версии. Убедитесь, что вы передаете каждый сгенерированный файл в систему контроля версий. В следующий раз, когда вы снова увеличите номер версии, Room сможет использовать файл JSON для тестирования.
- Флорина Мунтенеску ( источник)
build.gradle
android {
// [...]
defaultConfig {
// [...]
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
// add the schema location to the source sets
// used by Room, to test migrations
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
// [...]
}
Я использую .kts
Файлы Gradle (Kotlin Gradle DSL) и kotlin-kapt
плагин, но я все еще получаю ошибку компиляции скрипта, когда использую ответ Иванова Максима.
Unresolved reference: kapt
Для меня это было единственное, что сработало:
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
}
}
}
}
Просто публикую то, что сработало для меня, используя
Kotlin DSL
defaultConfig {
applicationId = ""
minSdk = 26
targetSdk = 33
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
//add this in the build.gradle.kts(app) file
javaCompileOptions {
annotationProcessorOptions {
arguments["room.schemaLocation"] =
"$projectDir/schemas"
}
}
}
Чтобы это работало, вам также необходимо установитьexportSchema
кtrue
@Database(entities = [Entity::class], version = 1, exportSchema = true)
@TypeConverters(Converters::class)
abstract class ScoresDatabase : RoomDatabase() {
abstract val dao: ScoresDAO
}
Чтобы убедиться, что это работает, вы должны увидеть вновь созданный каталог схем в корневом каталоге модуля со следующей сборкой, как показано ниже.
Котлинский способ согласно официальному документу :
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments += mapOf(
"room.schemaLocation" to "$projectDir/schemas",
"room.incremental" to "true",
"room.expandProjection" to "true"
)
}
}
}
}
Если, как и я, вы недавно переместили определенные классы в разные пакеты и т. Д. а вы используете Android-навигацию. Обязательно измените argType, чтобы он соответствовал новому адресу пакета. из:
app:argType="com.example.app.old.Item"
кому:
app:argType="com.example.app.new.Item"
// For javac or KAPT, configure using android DSL:
android {
...
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
compilerArgumentProviders(
RoomSchemaArgProvider(File(projectDir, "schemas"))
)
}
}
}
}
// For KSP, configure using KSP extension:
ksp {
arg(RoomSchemaArgProvider(File(projectDir, "schemas")))
}
Возможно, вы не добавили класс своей комнаты к ребенку RoomDatabase
дочерний класс в @Database(entities = {your_classes})
Если вы используете комнату с ksp в сборке модуля, вам необходимо определить RoomSchemaArgProvider.
class RoomSchemaArgProvider(
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
val schemaDir: File
) : CommandLineArgumentProvider {
override fun asArguments(): Iterable<String> {
// Note: If you're using KSP, change the line below to return
return listOf("room.schemaLocation=${schemaDir.path}")
// return listOf("-Aroom.schemaLocation=${schemaDir.path}")
}
}
android {
// For KSP, configure using KSP extension:
ksp {
arg(RoomSchemaArgProvider(File(projectDir, "schemas")))
}
}
А затем убедитесь, что у вас есть каталог в приложении/схемах. Не знаю, почему в моем случае он не был создан автоматически.