Phòng - Thư mục xuất lược đồ không được cung cấp cho bộ xử lý chú thích nên chúng tôi không thể xuất lược đồ


349

Tôi đang sử dụng phòng thành phần cơ sở dữ liệu Android

Tôi đã cấu hình mọi thứ, nhưng khi tôi biên dịch, Android Studio đưa ra cảnh báo này:

Thư mục xuất lược đồ không được cung cấp cho bộ xử lý chú thích nên chúng ta không thể xuất lược đồ. Bạn có thể cung cấp room.schemaLocationđối số bộ xử lý chú thích HOẶC đặt exportSchema thành false.

Theo tôi hiểu thì đó là vị trí đặt tệp DB

Làm thế nào nó có thể ảnh hưởng đến ứng dụng của tôi? Thực hành tốt nhất ở đây là gì? Tôi có nên sử dụng vị trí ( falsegiá trị) mặc định ?

Câu trả lời:


395

Theo các tài liệu :

Bạn có thể đặt đối số bộ xử lý chú thích (room.schemaLocation) để báo cho Room xuất lược đồ vào một thư mục. Mặc dù không bắt buộc, nhưng nên có lịch sử phiên bản trong cơ sở mã của bạn và bạn nên cam kết tệp đó vào hệ thống kiểm soát phiên bản của mình (nhưng không gửi nó cùng với ứng dụng của bạn!).

Vì vậy, nếu bạn không cần kiểm tra lược đồ và bạn muốn loại bỏ cảnh báo, chỉ cần thêm exportSchema = falsevào RoomDatabase, như sau.

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

Nếu bạn làm theo câu trả lời @mikejonesguy bên dưới, bạn sẽ tuân theo thực tiễn tốt được đề cập trong các tài liệu :). Về cơ bản, bạn sẽ nhận được một .jsontập tin trong ../app/schemas/thư mục của bạn . Và nó trông giống như thế này:

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

Nếu sự hiểu biết của tôi là chính xác, bạn sẽ nhận được một tệp như vậy với mỗi bản cập nhật phiên bản cơ sở dữ liệu, để bạn có thể dễ dàng theo dõi lịch sử của db của mình.


7
Điều đó thực sự có nghĩa là gì "Đừng giao hàng với ứng dụng của bạn"? Nó sẽ bao gồm trong APK?
Jongz Puangput

2
Nếu làm theo "Không gửi cùng với ứng dụng của bạn", tôi có nên xóa các tệp JSON trước khi tạo APK không?
ảo tưởngJJ

7
"Không gửi cùng với ứng dụng của bạn" có nghĩa là "Không đặt lược đồLocation như 'app / res / raw'. Đặt lược đồLocation vào một thư mục không có trong APK."
galcyurio

3
@galcyurio $ projectDir / schitions là một thư mục nằm ngoài APK, phải không? Tôi đã khám phá APK được tạo và tôi không thấy nó ở đó. Mặc dù tôi thấy / res (tài khoản cho app / src / main / res) chẳng hạn.
xarlymg89

1
@glucaio Tôi đã khám phá APK (và gói Ứng dụng nữa) và không tìm thấy nó. Vì vậy, tôi tin rằng chúng ta an toàn.
xarlymg89

388

Trong build.gradletệp cho mô-đun ứng dụng của bạn, hãy thêm phần này vào defaultConfigphần (bên dưới androidphần). Điều này sẽ viết lược đồ cho schemasthư mục con của thư mục dự án của bạn.

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

Như thế này:

// ...

android {

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

    defaultConfig {

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

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

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

}

// ...

34
Nếu bất cứ ai thắc mắc, cách tiếp cận chính xác này cũng hiệu quả với Kotlin khi sử dụng kapt
DanielDiSu

1
Chúng ta có nên gitignore tệp json được tạo trong app/schemasthư mục bằng thao tác này. Và tôi nghe nói chúng ta nên đặt lược đồ vào một thư mục không có trong apk. Làm thế nào chúng ta có thể làm điều đó?
ravi

2
@ravi (các) tệp lược đồ đã tạo nên được lưu trữ trong kiểm soát phiên bản vì Room được sử dụng để phát hiện các thay đổi và giúp đảm bảo nếu cơ sở dữ liệu thay đổi bạn cập nhật phiên bản cơ sở dữ liệu và tạo kế hoạch di chuyển
appmattus

1
Cấu hình này có ảnh hưởng đến phiên bản phát hành không? Ý tôi là, khi tôi xuất dự án sang một ứng dụng phát hành.
Anargu

Nếu giải pháp này dẫn đến LRI: Không thể tìm thấy chú thích phương thứcProcessorOptions () cho các đối số , hãy xem câu trả lời của Luna, bên dưới: stackoverflow.com/a/54366985/1617737
ban-Geoengineering

184

Kotlin? Ở đây chúng tôi đi:

android {

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

    defaultConfig {

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

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

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

//...

Đừng quên plugin:

apply plugin: 'kotlin-kapt'

Để biết thêm thông tin về bộ xử lý chú thích kotlin, vui lòng truy cập: Tài liệu của Kotlin


Giống như cách bạn trả lời: D
theapache64

12

Câu trả lời trên là chính xác. Phiên bản này rất dễ làm theo:

Vì "Thư mục xuất lược đồ không được cung cấp cho bộ xử lý chú thích", nên chúng tôi cần cung cấp thư mục để xuất lược đồ:

Bước [1] Trong tệp mở rộng RoomDatabase, hãy thay đổi dòng thành:

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

Hoặc là

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

(vì giá trị mặc định luôn luôn đúng)

Bước [2] Trong tệp build.gradle (dự án: ????) của bạn, bên trong defaultConfig {} (nằm trong phần lớn {} của android ), hãy thêm phần javaCompileOptions {} , nó sẽ như sau:

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

$ projectDir : là một tên biến, bạn không thể thay đổi nó. nó sẽ nhận được thư mục dự án của riêng bạn

lược đồ : là một chuỗi, bạn có thể thay đổi nó thành bất kỳ bạn thích. Ví dụ: "$projectDir/MyOwnSchemas".toString()


trong bước [2], bạn có chắc là nó build.gradle(project:????)không build.gradle(app:????)?
Ace

9

Câu trả lời @mikejonesguy là hoàn hảo, chỉ trong trường hợp bạn có kế hoạch kiểm tra di chuyển phòng (được khuyến nghị), hãy thêm vị trí lược đồ vào các bộ nguồn.

Trong tệp build.gradle của bạn, bạn chỉ định một thư mục để đặt các tệp JSON lược đồ được tạo này. Khi bạn cập nhật lược đồ của mình, bạn sẽ kết thúc với một số tệp JSON, một tệp cho mỗi phiên bản. Hãy chắc chắn rằng bạn cam kết mọi tệp được tạo để kiểm soát nguồn. Lần tới khi bạn tăng lại số phiên bản của mình, Room sẽ có thể sử dụng tệp JSON để thử nghiệm.

xây dựng. nâng cấp

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

Tôi sử dụng .ktscác tệp Gradle (Kotlin Gradle DSL) và kotlin-kaptplugin nhưng tôi vẫn gặp lỗi biên dịch tập lệnh khi tôi sử dụng câu trả lời của Ivanov Maksim.

Unresolved reference: kapt

Đối với tôi đây là điều duy nhất có tác dụng:

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

Không có gì là làm việc cho tôi cả. Tôi đang sử dụng Kotlin.
nyxee

0

Có lẽ bạn không thêm lớp phòng cho con RoomDatabaselớp trẻ trong@Database(entities = {your_classes})

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.