Raum - Das Schema-Exportverzeichnis wird dem Anmerkungsprozessor nicht zur Verfügung gestellt, daher können wir das Schema nicht exportieren

349

Ich verwende Android Database Component Room

Ich habe alles konfiguriert, aber beim Kompilieren gibt Android Studio folgende Warnung aus:

Das Schemaexportverzeichnis wird dem Anmerkungsprozessor nicht zur Verfügung gestellt, daher können wir das Schema nicht exportieren. Sie können entweder ein room.schemaLocationAnnotation Processor-Argument angeben oder exportSchema auf false setzen.

Soweit ich weiß, ist dies der Speicherort der DB-Datei

Wie kann sich das auf meine App auswirken? Was ist hier die beste Vorgehensweise? Soll ich den Standardspeicherort ( falseWert) verwenden?

Mischa Akopov
quelle

Antworten:

395

Gemäß den Dokumenten :

Sie können das Annotation Processor-Argument (room.schemaLocation) festlegen, um Room anzuweisen, das Schema in einen Ordner zu exportieren. Auch wenn dies nicht obligatorisch ist, empfiehlt es sich, den Versionsverlauf in Ihrer Codebasis zu haben, und Sie sollten diese Datei in Ihr Versionskontrollsystem übertragen (aber nicht mit Ihrer App ausliefern!).

Wenn Sie also das Schema nicht überprüfen müssen und die Warnung entfernen möchten, fügen exportSchema = falseSie sie einfach RoomDatabasewie folgt hinzu.

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

Wenn Sie der Antwort von @mikejonesguy unten folgen, befolgen Sie die in den Dokumenten genannten bewährten Methoden :). Grundsätzlich erhalten Sie eine .jsonDatei in Ihrem ../app/schemas/Ordner. Und es sieht ungefähr so ​​aus:

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

Wenn mein Verständnis korrekt ist, erhalten Sie bei jedem Update der Datenbankversion eine solche Datei, sodass Sie den Verlauf Ihrer Datenbank problemlos verfolgen können.

DoruChidean
quelle
7
Was bedeutet es wirklich "Nicht mit Ihrer App versenden"? Es wird in APK enthalten sein?
Jongz Puangput
2
Wenn ich "Nicht mit Ihrer App versenden" folge, sollte ich JSON-Dateien entfernen, bevor ich APK generiere?
IllusionJJ
7
"Nicht mit Ihrer App versenden" bedeutet "Setzen Sie schemaLocation nicht auf" app / res / raw ". Setzen Sie schemaLocation auf ein Verzeichnis, das nicht in der APK enthalten ist."
Galcyurio
3
@galcyurio $ projectDir / schemas ist ein Verzeichnis aus der APK, oder? Ich habe die generierte APK erkundet und sehe sie dort nicht. Obwohl ich zum Beispiel / res sehe (was App / src / main / res ausmacht).
Xarlymg89
1
@glucaio Ich habe die APK (und auch das App-Bundle) erkundet und nicht gefunden. Ich glaube, wir sind in Sicherheit.
Xarlymg89
388

build.gradleFügen Sie dies in der Datei für Ihr App-Modul dem defaultConfigAbschnitt (unter dem androidAbschnitt) hinzu. Dadurch wird das Schema in einen schemasUnterordner Ihres Projektordners geschrieben.

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

So was:

// ...

android {

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

    defaultConfig {

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

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

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

}

// ...
mikejonesguy
quelle
34
Wenn sich jemand wundert, funktioniert dieser genaue Ansatz auch für Kotlin, wenn kapt
DanielDiSu
1
Sollten wir die app/schemasdurch diesen Vorgang im Verzeichnis erzeugte JSON-Datei gitignore . Und ich habe gehört, wir sollten das Schema in ein Verzeichnis stellen, das nicht im enthalten ist apk. Wie können wir das machen?
Ravi
2
@ravi Die generierten Schemadateien sollten in der Versionskontrolle gespeichert werden, da dies von Room verwendet wird, um Änderungen zu erkennen und sicherzustellen, dass Sie die Datenbankversion aktualisieren und einen Migrationsplan erstellen
Appmattus
1
Beeinflusst diese Konfiguration die Release-Version? Ich meine, wenn ich das Projekt in eine Release-App exportiere.
Anargu
Wenn diese Lösung zu FEHLER führt: Die Methode annotationProcessorOptions () für Argumente konnte nicht gefunden werden , lesen Sie
ban-
184

Kotlin? Auf geht's:

android {

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

    defaultConfig {

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

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

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

//...

Plugin nicht vergessen:

apply plugin: 'kotlin-kapt'

Weitere Informationen zum Kotlin Annotation Processor finden Sie unter: Kotlin docs

Ivanov Maksim
quelle
So wie du es beantwortet hast: D
theapache64
12

Die obigen Antworten sind richtig. Diese Version ist leicht zu folgen:

Da "Schemaexportverzeichnis nicht für den Anmerkungsprozessor bereitgestellt wird", müssen wir das Verzeichnis für den Schemaexport bereitstellen:

Schritt [1] Ändern Sie in Ihrer Datei, die die RoomDatabase erweitert, die Zeile in:

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

Oder

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

(weil der Standardwert immer wahr ist)

Schritt [2] Fügen Sie in Ihrer Datei build.gradle (project: ????) in der Datei defaultConfig {} (die sich im großen Abschnitt android {} befindet ) den Abschnitt javaCompileOptions {} hinzu.

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

$ projectDir : ist ein Variablenname, den Sie nicht ändern können. Es wird Ihr eigenes Projektverzeichnis erhalten

schemas : ist eine Zeichenfolge, die Sie nach Belieben ändern können. Zum Beispiel: "$projectDir/MyOwnSchemas".toString()

LunaRivolxoxo
quelle
Sind Sie in Schritt [2] sicher, dass es das ist build.gradle(project:????)und nicht build.gradle(app:????)?
Ace
9

Die Antwort von @mikejonesguy ist perfekt. Falls Sie Raummigrationen testen möchten (empfohlen), fügen Sie den Schemaspeicherort zu den Quellensätzen hinzu.

In Ihrer build.gradle-Datei geben Sie einen Ordner an, in dem diese generierten Schema-JSON-Dateien abgelegt werden sollen. Wenn Sie Ihr Schema aktualisieren, erhalten Sie mehrere JSON-Dateien, eine für jede Version. Stellen Sie sicher, dass Sie jede generierte Datei der Quellcodeverwaltung übergeben. Wenn Sie Ihre Versionsnummer das nächste Mal erneut erhöhen, kann Room die JSON-Datei zum Testen verwenden.

  • Florina Muntenescu ( Quelle )

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
quelle
3

Ich verwende .ktsGradle-Dateien (Kotlin Gradle DSL) und das kotlin-kaptPlugin, erhalte jedoch immer noch einen Fehler beim Kompilieren von Skripten, wenn ich die Antwort von Ivanov Maksim verwende.

Unresolved reference: kapt

Für mich war dies das einzige, was funktionierte:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
            }
        }
    }
}
jsa
quelle
Auch für mich funktioniert nichts. Ich benutze Kotlin.
Nyxee
0

Wahrscheinlich haben Sie nicht Ihr Zimmer Klasse Kind hinzufügen RoomDatabaseKindklasse in@Database(entities = {your_classes})

Max Zonov
quelle