Salle - Le répertoire d'exportation de schéma n'est pas fourni au processeur d'annotation, nous ne pouvons donc pas exporter le schéma

350

J'utilise la salle de composants de base de données Android

J'ai tout configuré, mais quand je compile, Android Studio me donne cet avertissement:

Le répertoire d'exportation de schéma n'est pas fourni au processeur d'annotation, nous ne pouvons donc pas exporter le schéma. Vous pouvez soit fournir l' room.schemaLocationargument du processeur d'annotation OU définir exportSchema sur false.

Si je comprends bien, c'est l'emplacement où le fichier DB sera situé

Comment cela peut-il affecter mon application? Quelle est la meilleure pratique ici? Dois-je utiliser l'emplacement par défaut ( falsevaleur)?

Misha Akopov
la source

Réponses:

396

Selon les documents :

Vous pouvez définir l'argument du processeur d'annotations (room.schemaLocation) pour indiquer à Room d'exporter le schéma dans un dossier. Même si ce n'est pas obligatoire, c'est une bonne pratique d'avoir l'historique des versions dans votre base de code et vous devez valider ce fichier dans votre système de contrôle de version (mais ne le livrez pas avec votre application!).

Donc, si vous n'avez pas besoin de vérifier le schéma et que vous souhaitez vous débarrasser de l'avertissement, ajoutez simplement exportSchema = falseà votre RoomDatabase, comme suit.

@Database(entities = { YourEntity.class }, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
   //...
}

Si vous suivez la réponse @mikejonesguy ci-dessous, vous suivrez la bonne pratique mentionnée dans la documentation :). Fondamentalement, vous obtiendrez un .jsonfichier dans votre ../app/schemas/dossier. Et cela ressemble à ceci:

{
  "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\")"
    ]
  }
}

Si ma compréhension est correcte, vous obtiendrez un tel fichier avec chaque mise à jour de la version de la base de données, afin que vous puissiez facilement suivre l'historique de votre base de données.

DoruChidean
la source
8
Qu'est-ce que cela signifie vraiment "Ne pas expédier avec votre application"? Il sera inclus dans l'APK?
Jongz Puangput
2
Si suivez "Ne pas expédier avec votre application", dois-je supprimer les fichiers JSON avant de générer l'APK?
illusionJJ
8
«Ne pas expédier avec votre application» signifie «Ne définissez pas schemaLocation comme« app / res / raw ». Définissez schemaLocation dans un répertoire non inclus dans l'APK».
galcyurio
3
@galcyurio $ projectDir / schemas est un répertoire de l'APK, non? J'ai exploré l'APK généré et je ne le vois pas là-bas. Bien que je vois / res (qui représente app / src / main / res) par exemple.
xarlymg89
1
@glucaio J'ai exploré l'APK (et le bundle App aussi) et je ne l'ai pas trouvé. Je pense donc que nous sommes en sécurité.
xarlymg89
390

Dans le build.gradlefichier de votre module d'application, ajoutez-le à la defaultConfigsection (sous la androidsection). Cela écrira le schéma dans un schemassous - dossier de votre dossier de projet.

javaCompileOptions {
    annotationProcessorOptions {
        arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
    }
}

Comme ça:

// ...

android {

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

    defaultConfig {

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

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }

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

}

// ...
mikejonesguy
la source
35
Si quelqu'un se pose la
DanielDiSu
1
Faut-il gitignore le fichier json généré dans le app/schemasrépertoire par cette opération. Et j'ai entendu dire que nous devrions placer le schéma dans un répertoire qui n'est pas inclus dans le apk. Comment pouvons-nous faire cela?
ravi
2
@ravi le ou les fichiers de schéma générés doivent être stockés dans le contrôle de version car ils sont utilisés par Room pour détecter les modifications et garantir que si la base de données change, vous mettez à jour la version de la base de données et créez un plan de migration
appmattus
1
Cette configuration affecte-t-elle la version finale? Je veux dire, lorsque j'exporte le projet vers une application de version.
Anargu
Si cette solution se traduit par ERREUR: impossible de trouver la méthode annotationProcessorOptions () pour les arguments , consultez la réponse de Luna ci-dessous: stackoverflow.com/a/54366985/1617737
ban-geoengineering
185

Kotlin? Et c'est parti:

android {

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

    defaultConfig {

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

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

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

//...

N'oubliez pas le plugin:

apply plugin: 'kotlin-kapt'

Pour plus d'informations sur le processeur d'annotations kotlin, veuillez visiter: Kotlin docs

Ivanov Maksim
la source
Comme la façon dont vous y avez répondu: D
theapache64
12

Les réponses ci-dessus sont correctes. Cette version est facile à suivre:

Parce que "le répertoire d'exportation de schéma n'est pas fourni au processeur d'annotation", nous devons donc fournir le répertoire pour l'exportation de schéma:

Étape [1] Dans votre fichier qui étend la RoomDatabase, changez la ligne en:

`@Database(entities = ???.class,version = 1, exportSchema = true)`

Ou

`@Database(entities = ???.class,version = 1)` 

(car la valeur par défaut est toujours vraie)

Étape [2] Dans votre fichier build.gradle (projet: ????), à l'intérieur de la section defaultConfig {} (qui se trouve à l'intérieur de la grande section android {} ), ajoutez la section javaCompileOptions {} , ce sera comme:

         android{
                defaultConfig{
                      //javaComplieOptions SECTION
                      javaCompileOptions {
                            annotationProcessorOptions {
                                     arguments = ["room.schemaLocation":"$projectDir/schemas".toString()]
                            }
                       }
                      //Other SECTION
                      ...
                }
         }

$ projectDir : est un nom de variable, vous ne pouvez pas le changer. il obtiendra votre propre répertoire de projet

schémas : est une chaîne, vous pouvez la changer en celle que vous voulez. Par exemple: "$projectDir/MyOwnSchemas".toString()

LunaRivolxoxo
la source
à l'étape [2], êtes-vous sûr que c'est le build.gradle(project:????)et non build.gradle(app:????)?
Ace
9

La réponse @mikejonesguy est parfaite, juste au cas où vous prévoyez de tester les migrations de salle (recommandé), ajoutez l'emplacement du schéma aux ensembles source.

Dans votre fichier build.gradle, vous spécifiez un dossier pour placer ces fichiers JSON de schéma générés. Lorsque vous mettez à jour votre schéma, vous vous retrouverez avec plusieurs fichiers JSON, un pour chaque version. Assurez-vous de valider chaque fichier généré pour le contrôle de code source. La prochaine fois que vous augmenterez à nouveau votre numéro de version, Room pourra utiliser le fichier JSON pour les tests.

  • Florina Muntenescu ( source )

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())
    }

    // [...]
}
chebaby
la source
3

J'utilise des .ktsfichiers Gradle (Kotlin Gradle DSL) et le kotlin-kaptplugin mais j'obtiens toujours une erreur de compilation de script lorsque j'utilise la réponse d'Ivanov Maksim.

Unresolved reference: kapt

Pour moi, c'est la seule chose qui a fonctionné:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
            }
        }
    }
}
jsa
la source
Rien ne fonctionne pour moi non plus. J'utilise Kotlin.
nyxee
0

Vous n'avez probablement pas ajouté votre classe de chambre à la classe enfant RoomDatabaseenfant dans@Database(entities = {your_classes})

Max Zonov
la source