Kamar - Direktori ekspor skema tidak disediakan untuk prosesor anotasi sehingga kami tidak dapat mengekspor skema

349

Saya menggunakan Kamar Komponen Database Android

Saya sudah mengkonfigurasi semuanya, tetapi ketika saya kompilasi, Android Studio memberi saya peringatan ini:

Direktori ekspor skema tidak disediakan untuk prosesor anotasi sehingga kami tidak dapat mengekspor skema. Anda dapat memberikan room.schemaLocationargumen prosesor anotasi ATAU mengatur exportSchema ke false.

Seperti yang saya mengerti itu adalah lokasi di mana file DB akan berada

Bagaimana pengaruhnya terhadap aplikasi saya? Apa praktik terbaik di sini? Haruskah saya menggunakan lokasi ( falsenilai) default ?

Misha Akopov
sumber

Jawaban:

395

Sesuai dokumen :

Anda dapat mengatur argumen prosesor anotasi (room.schemaLocation) untuk memberi tahu Room untuk mengekspor skema ke folder. Meskipun tidak wajib, ini adalah praktik yang baik untuk memiliki riwayat versi di basis kode Anda dan Anda harus memasukkan file itu ke dalam sistem kontrol versi Anda (tetapi jangan kirimkan bersama aplikasi Anda!).

Jadi, jika Anda tidak perlu memeriksa skema dan Anda ingin menyingkirkan peringatan itu, tambahkan saja exportSchema = falsepada Anda RoomDatabase, sebagai berikut.

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

Jika Anda mengikuti jawaban @mikejonesguy di bawah ini, Anda akan mengikuti praktik baik yang disebutkan dalam dokumen :). Pada dasarnya Anda akan mendapatkan .jsonfile di ../app/schemas/folder Anda . Dan terlihat seperti ini:

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

Jika pemahaman saya benar, Anda akan mendapatkan file seperti itu dengan setiap pembaruan versi basis data, sehingga Anda dapat dengan mudah mengikuti sejarah db Anda.

DoruChidean
sumber
7
Apa maksudnya "Jangan kirim dengan aplikasi Anda"? Ini akan dimasukkan dalam APK?
Jongz Puangput
2
Jika mengikuti "Jangan kirim dengan aplikasi Anda", haruskah saya menghapus file JSON sebelum membuat APK?
illusionJJ
7
"Jangan kirim dengan aplikasi Anda" berarti "Jangan setel schemaLocation seperti 'app / res / raw'. Setel schemaLocation ke direktori yang tidak termasuk dalam APK."
galcyurio
3
@galcyurio $ projectDir / schemas adalah direktori dari APK, kan? Saya telah menjelajahi APK yang dihasilkan dan saya tidak melihatnya di sana. Meskipun saya melihat / res (yang menyumbang app / src / main / res) misalnya.
xarlymg89
1
@glucaio Saya menjelajahi APK (dan bundel App juga) dan tidak menemukannya. Jadi saya yakin kita aman.
xarlymg89
388

Dalam build.gradlefile untuk modul aplikasi Anda, tambahkan ini ke defaultConfigbagian (di bawah androidbagian). Ini akan menulis skema ke schemassubfolder dari folder proyek Anda.

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

Seperti ini:

// ...

android {

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

    defaultConfig {

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

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

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

}

// ...
mikejonesguy
sumber
34
Jika ada yang bertanya-tanya, pendekatan yang tepat ini juga berfungsi untuk Kotlin ketika menggunakan kapt
DanielDiSu
1
Haruskah kita gitignore file json yang dihasilkan dalam app/schemasdirektori oleh operasi ini. Dan saya dengar kita harus meletakkan skema ke direktori yang tidak termasuk dalam apk. Bagaimana kita bisa melakukan itu?
ravi
2
@ravi file skema yang dihasilkan harus disimpan dalam kontrol versi karena ini digunakan oleh Room untuk mendeteksi perubahan dan membantu memastikan jika database mengubah Anda memperbarui versi database dan membuat rencana migrasi
appmattus
1
Apakah konfigurasi ini memengaruhi versi rilis? Maksud saya, ketika saya mengekspor proyek ke aplikasi rilis.
Anargu
Jika solusi ini menghasilkan ERROR: Tidak dapat menemukan metode annotationProcessorOptions () untuk argumen , periksa jawaban Luna, di bawah ini: stackoverflow.com/a/54366985/1617737
larangan geoengineering
184

Kotlin? Kita mulai:

android {

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

    defaultConfig {

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

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

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

//...

Jangan lupa tentang plugin:

apply plugin: 'kotlin-kapt'

Untuk informasi lebih lanjut tentang prosesor anotasi kotlin, silakan kunjungi: Kotlin docs

Ivanov Maksim
sumber
Seperti cara Anda menjawabnya: D
theapache64
12

Jawaban di atas benar. Versi ini mudah diikuti:

Karena "Direktori ekspor skema tidak disediakan untuk prosesor anotasi", Jadi kami perlu menyediakan direktori untuk skema ekspor:

Langkah [1] Di file Anda yang memperluas RoomDatabase, ubah baris menjadi:

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

Atau

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

(karena nilai default selalu benar)

Langkah [2] Di file build.gradle (project: ????) Anda, di dalam defaultConfig {} (yang ada di dalam bagian besar android {} ), tambahkan bagian javaCompileOptions {} , akan menjadi seperti:

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

$ projectDir : adalah nama variabel, Anda tidak dapat mengubahnya. itu akan mendapatkan direktori proyek Anda sendiri

skema : adalah string, Anda dapat mengubahnya ke apa pun yang Anda suka. Sebagai contoh: "$projectDir/MyOwnSchemas".toString()

LunaRivolxoxo
sumber
pada langkah [2], apakah Anda yakin itu build.gradle(project:????)dan tidak build.gradle(app:????)?
Ace
9

@mikejonesguy jawaban sempurna, kalau-kalau Anda berencana untuk menguji migrasi kamar (disarankan), tambahkan lokasi skema ke set sumber.

Dalam file build.gradle Anda, Anda menentukan folder untuk menempatkan file JSON skema yang dihasilkan ini. Saat Anda memperbarui skema Anda, Anda akan berakhir dengan beberapa file JSON, satu untuk setiap versi. Pastikan Anda mengkomit setiap file yang dihasilkan ke kontrol sumber. Lain kali Anda menambah nomor versi lagi, Room akan dapat menggunakan file JSON untuk pengujian.

  • Florina Muntenescu ( sumber )

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

    // [...]
}
dingin
sumber
3

Saya menggunakan .ktsfile Gradle (Kotlin Gradle DSL) dan kotlin-kaptplugin tetapi saya masih mendapatkan kesalahan kompilasi skrip ketika saya menggunakan jawaban Ivanov Maksim.

Unresolved reference: kapt

Bagi saya ini adalah satu-satunya hal yang berhasil:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
            }
        }
    }
}
jsa
sumber
Tidak ada yang bekerja untuk saya juga. Saya menggunakan Kotlin.
nyxee
0

Mungkin Anda tidak menambahkan kelas kamar Anda ke kelas anak RoomDatabasekecil@Database(entities = {your_classes})

Max Zonov
sumber