Room - 模式导出目录未提供给注释处理器,因此我们无法导出模式

Room - Schema export directory is not provided to the annotation processor so we cannot export the schema

我正在使用 Android 数据库组件室

我已经配置了一切,但是当我编译时,Android Studio 给了我这个警告:

Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide room.schemaLocation annotation processor argument OR set exportSchema to false.

据我了解,这是数据库文件所在的位置

它如何影响我的应用程序?这里的最佳做法是什么?我应该使用默认位置(false 值)吗?

在您的应用程序模块的 build.gradle 文件中,将其添加到 defaultConfig 部分(在 android 部分下)。这会将架构写出到项目文件夹的 schemas 子文件夹中。

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

像这样:

// ...

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

    defaultConfig {

        // ... (applicationId, miSdkVersion, etc)
        
        javaCompileOptions {
            annotationProcessorOptions {
                arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }
   
    // ... (buildTypes, compileOptions, etc)

}

// ...

根据 docs:

You can set annotation processor argument (room.schemaLocation) to tell Room to export the schema into a folder. Even though it is not mandatory, it is a good practice to have version history in your codebase and you should commit that file into your version control system (but don't ship it with your app!).

因此,如果您不需要检查架构并且想要摆脱警告,只需将 exportSchema = false 添加到您的 RoomDatabase,如下所示。

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

如果您关注下面的@mikejonesguy ,您将遵循文档中提到的良好做法:)。 基本上,您会在 ../app/schemas/ 文件夹中获得一个 .json 文件。 它看起来像这样:

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

如果我的理解是正确的,你会在每次数据库版本更新时得到这样一个文件,这样你就可以很容易地跟踪你的数据库的历史。

科特林?我们开始吧:

android {

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

    defaultConfig {

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

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

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

//...

别忘了插件:

apply plugin: 'kotlin-kapt'

更多关于kotlin注解处理器的信息请访问: Kotlin docs

@mikejonesguy 是完美的,以防万一您计划测试房间迁移(推荐),将模式位置添加到源集中。

In your build.gradle file you specify a folder to place these generated schema JSON files. As you update your schema, you’ll end up with several JSON files, one for every version. Make sure you commit every generated file to source control. The next time you increase your version number again, Room will be able to use the JSON file for testing.

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

    // [...]
}

以上回答正确。这个版本简单易学:

因为"Schema export directory is not provided to the annotation processor",所以我们需要提供schema导出的目录:

Step [1] In your file which extends the RoomDatabase, change the line to:

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

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

(因为默认值始终为真)

Step [2] In your build.gradle(project:????) file, inside the defaultConfig{ } (which is inside android{ } big section), add the javaCompileOptions{ } section, it will be like:

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

$projectDir:是一个变量名,不能更改。它会得到你自己的项目目录

schemas:是一个字符串,你可以改成任何你喜欢的。例如: "$projectDir/MyOwnSchemas".toString()

我使用 .kts Gradle 文件(Kotlin Gradle DSL)和 kotlin-kapt 插件,但当我使用 Ivanov Maksim 的答案时,我仍然遇到脚本编译错误。

Unresolved reference: kapt

对我来说,这是唯一有效的方法:

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

可能您没有将房间 class 添加到 child RoomDatabase child class @Database(entities = {your_classes})

如果你像我一样最近将某些 类 移动到不同的包等。并且您使用 android 导航。确保更改 argType 以匹配您的新包裹地址。 来自:

app:argType="com.example.app.old.Item" 

至:

app:argType="com.example.app.new.Item" 

Kotlin 方法根据 official document:

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

对于 Kotlin KSP:

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