Raum – Schema-Exportverzeichnis wird dem Anmerkungsprozessor nicht bereitgestellt, sodass wir das Schema nicht exportieren können

Lesezeit: 6 Minuten

Benutzer-Avatar
Mischa Akopow

Ich verwende den Android Database Component Room

Ich habe alles konfiguriert, aber beim Kompilieren gibt mir Android Studio diese Warnung:

Das Schemaexportverzeichnis wird dem Anmerkungsprozessor nicht bereitgestellt, sodass wir das Schema nicht exportieren können. Sie können entweder bereitstellen
room.schemaLocation Argument des Anmerkungsprozessors ODER setze exportSchema auf false.

Soweit ich weiß, ist dies der Ort, an dem sich die DB-Datei befindet

Wie kann es meine App beeinflussen? Was ist hier die beste Praxis? Soll ich den Standardspeicherort verwenden (false Wert)?

Benutzer-Avatar
mikejonesguy

In dem build.gradle Datei für Ihr App-Modul, fügen Sie diese der defaultConfig Abschnitt (unter der android Sektion). Dadurch wird das Schema in a geschrieben schemas Unterordner Ihres Projektordners.

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)

}

// ...

  • Wenn sich jemand fragt, funktioniert genau dieser Ansatz auch für Kotlin bei der Verwendung Kapt

    – DanielDiSu

    2. Dezember 2017 um 11:40 Uhr

  • Sollten wir die JSON-Datei ignorieren, die in der app/schemas Verzeichnis durch diese Operation. Und ich habe gehört, wir sollten das Schema in ein Verzeichnis legen, das nicht in der enthalten ist apk. Wie können wir das machen?

    – Ravi

    8. Juli 2018 um 9:57 Uhr

  • @ravi Die generierten Schemadateien sollten in der Versionskontrolle gespeichert werden, da diese von Room verwendet wird, um Änderungen zu erkennen und sicherzustellen, dass Sie die Datenbankversion aktualisieren und einen Migrationsplan erstellen, wenn sich die Datenbank ändert

    – appmattus

    27. August 2018 um 7:54 Uhr

  • verwenden arguument += Es stört also nicht Ihre DI-Bibliotheken wie Hilt. (Weitere Informationen finden Sie in dieser Antwort unter stackoverflow.com/a/62891182/5780236)

    – Ahmad Reza Enshaee

    27. September 2020 um 14:11 Uhr


  • @ChantellOsejo wurde gerade aktualisiert. “Argumente = …” in “Argumente += …” geändert.

    – mikejonesguy

    20. Januar 2021 um 1:11 Uhr

Benutzer-Avatar
DoruChidean

Gemäß der Dokumente:

Sie können das Argument des Anmerkungsprozessors (room.schemaLocation) festlegen, um Room anzuweisen, das Schema in einen Ordner zu exportieren. Auch wenn es nicht obligatorisch ist, ist es eine gute Praxis, einen 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 loswerden möchten, fügen Sie einfach hinzu exportSchema = false zu deinem RoomDatabasefolgendermaßen.

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

Wenn Sie der Antwort von @mikejonesguy unten folgen, folgen Sie den bewährten Verfahren, die in den Dokumenten erwähnt werden :). Grundsätzlich erhalten Sie eine .json Datei in Ihrer ../app/schemas/ Mappe. Und es sieht in etwa 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 ich das richtig verstehe, erhalten Sie mit jedem Update der Datenbankversion eine solche Datei, damit Sie die Historie Ihrer db problemlos verfolgen können.

  • Was bedeutet „Nicht mit Ihrer App versenden“ wirklich? Es wird in APK enthalten sein?

    – Jongz Puangput

    10. März 2018 um 0:48 Uhr

  • Wenn ich „Nicht mit Ihrer App versenden“ befolge, sollte ich JSON-Dateien entfernen, bevor ich APK erzeuge?

    – IllusionJJ

    15. Mai 2018 um 2:47 Uhr

  • „Nicht mit Ihrer App ausliefern“ bedeutet „SchemaLocation nicht auf „app/res/raw“ setzen. SchemaLocation auf ein Verzeichnis setzen, das nicht im APK enthalten ist.“

    – galcyurio

    6. Juli 2018 um 9:38 Uhr

  • @galcyurio $projectDir/schemas ist ein Verzeichnis aus dem APK, richtig? Ich habe das generierte APK untersucht und sehe es dort drüben nicht. Obwohl ich zum Beispiel /res sehe (was app/src/main/res berücksichtigt).

    – xarlymg89

    11. Juli 2018 um 9:55 Uhr

  • @xarlymg89 Konntest du das bestätigen $projectDir/schemas ist NICHT in der APK enthalten? Laut dieser Antwort sind benutzerdefinierte Unterverzeichnisse dies nicht.

    Benutzer11566289

    18. Juli 2019 um 12:31 Uhr


Benutzer-Avatar
Iwanow Maksim

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-Anmerkungsprozessor finden Sie unter:
Kotlin-Dokumente

  • Ich bekam ein > No signature of method: build_xyz.android() is applicable for argument types: (build_xyz$_run_closure1) values: [[email protected]] wo xyz ist eine lange zufällige Zeichenfolge … ist es ein Fehler?

    – Minh Nghĩa

    24. November 2020 um 15:08 Uhr


  • Dies ist wahrscheinlich die bessere Option

    – sprajagopal

    13. Juni 2021 um 13:36 Uhr

  • Die obige Antwort von @mikejonesguy hat bei mir funktioniert.

    – sprajagopal

    13. Juni 2021 um 13:45 Uhr

  • Dasselbe Problem hier mit der fehlenden Signaturmethode.

    – Akito

    9. Oktober 2021 um 21:21 Uhr

  • Bei der Verwendung von javaCompileOptions, wie von anderen Antworten vorgeschlagen, wurde ein Fehler “Verursacht durch: groovy.lang.MissingMethodException: Keine Signatur der Methode: build_….android() ist anwendbar für Argumenttypen … “. Es sieht so aus, als ob javaCompileOptions veraltet sein könnte. Ich verwende AGP v7.0.2. Ich musste stattdessen kapt{} verwenden, um das Argument wie von Ivanov beschrieben festzulegen (ich habe es in Android{} verwendet und das Schema wurde ausgegeben).

    – Olli C

    19. Oktober 2021 um 9:45 Uhr

Die obigen Antworten sind richtig. Diese Version ist leicht nachzuvollziehen:

Da “Schema-Exportverzeichnis dem Anmerkungsprozessor nicht bereitgestellt wird”, müssen wir das Verzeichnis für den Schema-Export 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] In Ihrer build.gradle(project:????)-Datei, innerhalb der defaultConfig{ } (was drin ist Android{ } großer Abschnitt), fügen Sie die hinzu javaCompileOptions{ } Abschnitt, es wird wie folgt sein:

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

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

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

Die Antwort von @mikejonesguy ist perfekt, nur für den Fall, dass Sie Raummigrationen testen möchten (empfohlen), fügen Sie den Schemaspeicherort zu den Quellsätzen hinzu.

In Ihrer build.gradle-Datei geben Sie einen Ordner an, um diese generierten Schema-JSON-Dateien zu platzieren. Wenn Sie Ihr Schema aktualisieren, erhalten Sie am Ende 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 wieder erhöhen, kann Room die JSON-Datei zum Testen verwenden.

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

    // [...]
}

Benutzer-Avatar
Eyjafl

Für Kotlin KSP:

ksp {
    arg('room.schemaLocation', "$projectDir/schemas")
}

Benutzer-Avatar
jsa

ich benutze .kts Gradle-Dateien (Kotlin Gradle DSL) und die kotlin-kapt plugin, aber ich erhalte immer noch einen Skriptkompilierungsfehler, wenn ich die Antwort von Ivanov Maksim verwende.

Unresolved reference: kapt

Für mich war das das einzige, was funktioniert hat:

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

  • Bei mir funktioniert auch nichts. Ich verwende Kotlin.

    – nyxee

    6. April 2020 um 21:42 Uhr


  • Wie funktioniert diese Antwort? arguments ist eine MutableMap, val arguments: MutableMap<String, String> und gibt Kompilierfehler, wenn Sie versuchen, etwas zuzuweisen und mit hinzuzufügen arguments["room.schemaLocation"] ="$projectDir/schemas"funktioniert bei mir nicht. Andere Antwort funktioniert auch nicht.

    – Thrakisch

    30. August 2020 um 12:34 Uhr


1352220cookie-checkRaum – Schema-Exportverzeichnis wird dem Anmerkungsprozessor nicht bereitgestellt, sodass wir das Schema nicht exportieren können

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy