462

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

我已经配置了所有东西,但是当我编译时,Android Studio 给了我这个警告:

模式导出目录未提供给注释处理器,因此我们无法导出模式。您可以提供 room.schemaLocation注释处理器参数或将 exportSchema 设置为 false。

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

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

4

9 回答 9

500

根据文档

您可以设置注释处理器参数 (room.schemaLocation) 来告诉 Room 将架构导出到文件夹中。尽管这不是强制性的,但在您的代码库中拥有版本历史记录是一个很好的做法,并且您应该将该文件提交到您的版本控制系统中(但不要将它与您的应用程序一起发布!)。

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

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

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

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

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

于 2017-06-20T06:58:36.093 回答
493

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)

}

// ...
于 2017-06-08T00:44:05.830 回答
276

科特林?开始了:

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

于 2018-02-07T22:23:08.427 回答
18

以上答案都是正确的。这个版本很容易理解:

因为“Schema导出目录没有提供给注解处理器”,所以我们需要提供Schema导出的目录:

步骤 [1] 在扩展 RoomDatabase 的文件中,将行更改为:

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

或者

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

(因为默认值始终为 true)

步骤 [2] 在您的 build.gradle(project:????) 文件中,在defaultConfig{ }(在android{ }大部分内)中,添加javaCompileOptions{ }部分,它将如下所示:

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

$projectDir : 是一个变量名,你不能改变它。它将获得您自己的项目目录

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

于 2019-01-25T14:12:01.023 回答
13

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

在您的 build.gradle 文件中,您指定一个文件夹来放置这些生成的模式 JSON 文件。更新架构时,您最终会得到多个 JSON 文件,每个版本一个。确保将每个生成的文件提交到源代码管理。下次您再次增加版本号时,Room 将能够使用 JSON 文件进行测试。

构建.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())
    }

    // [...]
}
于 2018-11-02T09:45:12.590 回答
4

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

Unresolved reference: kapt

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

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
            }
        }
    }
}
于 2019-09-13T08:43:10.090 回答
1

如果像我一样,您最近将某些类移动到不同的包等。你使用安卓导航。确保将 argType 更改为与您的新包地址匹配。从:

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

至:

app:argType="com.example.app.new.Item" 
于 2020-11-28T21:32:54.967 回答
1

根据官方文档的Kotlin方式:

android {
...
defaultConfig {
    ...
    javaCompileOptions {
        annotationProcessorOptions {
            arguments += mapOf(
                "room.schemaLocation" to "$projectDir/schemas",
                "room.incremental" to "true",
                "room.expandProjection" to "true"
            )
        }
    }
}
}
于 2022-01-22T11:34:15.783 回答
0

可能你没有将你的房间类添加到RoomDatabase子类中@Database(entities = {your_classes})

于 2019-09-26T09:27:17.350 回答