Кімната - Каталог експорту схем не надається процесору анотацій, тому ми не можемо експортувати схему


350

Я використовую Компонентний номер бази даних Android

Я все налаштував, але коли я компілюю, Android Studio видає мені це попередження:

Каталог експорту схем не надається процесору анотацій, тому ми не можемо експортувати схему. Ви можете надати room.schemaLocationаргумент процесора приміток АБО встановити exportSchema на значення false.

Як я розумію, це місце розташування файлу БД

Як це може вплинути на мій додаток? Яка тут найкраща практика? Чи слід використовувати розташування за замовчуванням ( falseзначення)?

Відповіді:


396

Відповідно до документів :

Ви можете встановити аргумент процесора анотацій (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\")"
    ]
  }
}

Якщо я розумію правильно, ви отримаєте такий файл з кожним оновленням версії бази даних, щоб ви могли легко стежити за історією вашого db.


8
Що це насправді означає "Не постачайте разом із вашим додатком"? Він буде включений в APK?
Jongz Puangput

2
Якщо дотримуйтесь "Не постачайте разом із вашим додатком", чи слід видалити файли JSON перед створенням APK?
illusionJJ

8
"Не надсилайте програму" означає "Не встановлюйте schemaLocation таким чином, як" app / res / raw ". Встановіть схему розташування до каталогу, не включеного в APK."
galcyurio

3
@galcyurio $ projectDir / схеми - це каталог із APK, правда? Я дослідив створений APK і не бачу його там. Хоча я бачу / res (наприклад, що додає app / src / main / res).
xarlymg89

1
@glucaio Я дослідив APK (і пакет додатків) і не знайшов його. Тож я вважаю, що ми в безпеці.
xarlymg89

390

У 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)

}

// ...

35
Якщо хтось цікавиться, цей точний підхід також працює для Котліна
DanielDiSu

1
Якщо ми маємо ігнорувати файл json, згенерований у app/schemasкаталозі цією операцією. І я чув, що ми повинні помістити схему в каталог, який не включений у apk. Як ми можемо це зробити?
ravi

2
@ravi генеровані файли схем слід зберігати в контролі версій, оскільки це використовується Room для виявлення змін та допомоги для того, щоб змінити базу даних, ви оновите версію бази даних та створите план міграції
appmattus

1
Чи впливає ця конфігурація на версію випуску? Я маю на увазі, коли я експортую проект у програму для випуску.
Анаргу

Якщо це рішення призводить до помилки: Не вдалося знайти анотацію методуProcessorOptions () для аргументів , ознайомтеся з відповіддю Луни нижче: stackoverflow.com/a/54366985/1617737
ban-

185

Котлін? Ось і ми:

android {

    // ... (compileSdkVersion, buildToolsVersion, etc)

    defaultConfig {

        // ... (applicationId, miSdkVersion, etc)

        kapt {
            arguments {
                arg("room.schemaLocation", "$projectDir/schemas")
            }
        }
    }

    buildTypes {
        // ... (buildTypes, compileOptions, etc)
    }
}

//...

Не забудьте про плагін:

apply plugin: 'kotlin-kapt'

Для отримання додаткової інформації про процесор анотацій kotlin відвідайте: Документи Kotlin


Як і те, як ви відповіли на нього: D
theapache64

12

Вище відповіді правильні. Цю версію легко дотримуватися:

Оскільки "каталог експорту схеми не надається процесору анотацій", тому нам потрібно надати каталог для експорту схем:

Крок [1] ​​У файлі, який розширює базу даних RoomData, змініть рядок на:

`@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()


на кроці [2] ви впевнені, що це build.gradle(project:????)та ні build.gradle(app:????)?
Туз

9

Відповідь @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())
    }

    // [...]
}

3

Я використовую .ktsфайли Gradle (Kotlin Gradle DSL) та kotlin-kaptплагін, але я все одно отримую помилку компіляції сценаріїв, коли використовую відповідь Іванова Максима.

Unresolved reference: kapt

Для мене це працювало єдине:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
            }
        }
    }
}

Для мене теж нічого не працює. Я використовую Котлін.
nyxee

0

Можливо , ви не додати клас кімната для дитини RoomDatabaseклас дитини в@Database(entities = {your_classes})

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.