Room-스키마 내보내기 디렉토리가 주석 프로세서에 제공되지 않으므로 스키마를 내보낼 수 없습니다


350

Android Database Component Room을 사용하고 있습니다

모든 것을 구성했지만 컴파일 할 때 Android Studio에서 다음 경고를 표시합니다.

스키마 내보내기 디렉토리는 주석 프로세서에 제공되지 않으므로 스키마를 내보낼 수 없습니다. room.schemaLocation주석 프로세서 인수 를 제공하거나 exportSchema를 false로 설정할 수 있습니다 .

알다시피 DB 파일이있는 위치입니다.

앱에 어떤 영향을 줄 수 있습니까? 가장 좋은 방법은 무엇입니까? 기본 위치 ( false값)를 사용해야 합니까?

답변:


396

당으로 문서 :

주석 프로세서 인수 (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\")"
    ]
  }
}

내 이해가 정확하면 모든 데이터베이스 버전 업데이트와 함께 그러한 파일을 얻을 수 있으므로 DB 기록을 쉽게 따를 수 있습니다.


8
"앱과 함께 제공되지 않음"은 무엇을 의미합니까? APK에 포함됩니까?
Jongz Puangput 2016 년

2
"앱과 함께 제공되지 않음"에 따라 APK를 생성하기 전에 JSON 파일을 제거해야합니까?
illusionJJ

8
"앱과 함께 제공되지 않음"은 "schemaLocation을 'app / res / raw"와 같이 설정하지 마십시오. schemaLocation을 APK에 포함되지 않은 디렉토리로 설정하십시오. "
galcyurio

3
@galcyurio $ projectDir / schemas는 APK의 디렉토리입니다. 생성 된 APK를 살펴 봤는데 거기서 볼 수 없습니다. 예를 들어 / res (app / src / main / res를 설명하는)가 표시됩니다.
xarlymg89

1
@glucaio 나는 APK (및 앱 번들도)를 탐색했지만 찾지 못했습니다. 그래서 우리는 안전하다고 생각합니다.
xarlymg89

390

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)

}

// ...

35
사람이 궁금해하는 경우 사용하는 경우,이 정확한 접근 방식은 또한 코 틀린 작동 kapt
DanielDiSu

1
app/schemas이 작업으로 디렉토리에 생성 된 json 파일을 gitignore해야 합니다. 그리고 스키마에 포함되지 않은 디렉토리에 스키마를 넣어야한다고 들었습니다 apk. 우리는 어떻게 할 수 있습니까?
ravi

2
@ravi 생성 된 스키마 파일은 Room에서 변경 사항을 감지하고 데이터베이스 변경 사항이 데이터베이스 버전을 업데이트하고 마이그레이션 계획을 작성하는지 확인하는 데 사용되므로 버전 제어에 저장해야합니다.
appmattus

1
이 구성이 릴리스 버전에 영향을 줍니까? 프로젝트를 릴리스 앱으로 내보낼 때 의미합니다.
Anargu

이 솔루션 결과 경우 오류 : 인수 () 메소드의 annotationProcessorOptions을 찾을 수 없습니다 , 아래, 루나의 답변을 확인 : stackoverflow.com/a/54366985/1617737
금지 - 지구 공학

185

코 틀린? 여기 우리는 간다 :

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 를 방문하십시오.


당신이 대답 한 방식처럼 : D
theapache64

12

위의 답변이 맞습니다. 이 버전은 따르기 쉽습니다.

"스키마 내보내기 디렉토리는 주석 프로세서에 제공되지 않기 때문에"스키마 내보내기를위한 디렉토리를 제공해야합니다.

단계 [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 : 변수 이름이므로 변경할 수 없습니다. 그것은 당신의 자신의 프로젝트 디렉토리를 얻을 것입니다

스키마 : 문자열이며 원하는대로 변경할 수 있습니다. 예를 들면 다음과 같습니다. "$projectDir/MyOwnSchemas".toString()


[2] 단계에서 확실 build.gradle(project:????)하지 build.gradle(app:????)않습니까?
에이스

9

@mikejonesguy 답변 은 룸 마이그레이션을 테스트하려는 경우 (권장) 스키마 세트를 소스 세트에 추가하려는 경우에 적합합니다.

build.gradle 파일에서 생성 된 스키마 JSON 파일을 배치 할 폴더를 지정하십시오. 스키마를 업데이트하면 모든 버전마다 하나씩 여러 개의 JSON 파일이 생깁니다. 생성 된 모든 파일을 소스 제어에 커미트해야합니다. 다음에 버전 번호를 다시 늘리면 Room에서 테스트에 JSON 파일을 사용할 수 있습니다.

  • Florina Muntenescu ( 소스 )

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

    // [...]
}

3

내가 사용 .ktsGradle을 파일 (코 틀린 Gradle을 DSL)과 kotlin-kapt플러그인을하지만 이바노프 막심의 답변을 사용할 때 나는 아직도 스크립트 컴파일 오류가 발생합니다.

Unresolved reference: kapt

나에게 이것은 유일하게 작동 한 것입니다.

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

아무것도 나를 위해 일하고 있지 않습니다. 나는 Kotlin을 사용하고 있습니다.
nyxee

0

아마 당신은 룸 클래스를 하위 클래스에 추가하지 않았을 것 RoomDatabase입니다.@Database(entities = {your_classes})

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.