कक्ष - स्कीमा निर्यात निर्देशिका एनोटेशन प्रोसेसर को प्रदान नहीं की जाती है, इसलिए हम स्कीमा को निर्यात नहीं कर सकते हैं


350

मैं Android डेटाबेस घटक कक्ष का उपयोग कर रहा हूं

मैंने सब कुछ कॉन्फ़िगर किया है, लेकिन जब मैं संकलन करता हूं, तो एंड्रॉइड स्टूडियो मुझे यह चेतावनी देता है:

स्कीमा निर्यात निर्देशिका एनोटेशन प्रोसेसर को प्रदान नहीं की जाती है, इसलिए हम स्कीमा को निर्यात नहीं कर सकते हैं। आप या तो room.schemaLocationएनोटेशन प्रोसेसर तर्क प्रदान कर सकते हैं या एक्सपोर्टस्चेमा को गलत पर सेट कर सकते हैं ।

जैसा कि मैं समझता हूं कि यह वह स्थान है जहां डीबी फ़ाइल स्थित होगी

यह मेरे ऐप को कैसे प्रभावित कर सकता है? यहां सबसे अच्छा अभ्यास क्या है? क्या मुझे डिफ़ॉल्ट स्थान ( falseमान) का उपयोग करना चाहिए ?

जवाबों:


396

डॉक्स के अनुसार :

आप स्कीमा को एक फ़ोल्डर में निर्यात करने के लिए रूम बताने के लिए एनोटेशन प्रोसेसर तर्क (room.schemaLocation) सेट कर सकते हैं। हालांकि यह अनिवार्य नहीं है, यह आपके कोडबेस में संस्करण इतिहास रखने के लिए एक अच्छा अभ्यास है और आपको उस फ़ाइल को अपने संस्करण नियंत्रण प्रणाली में करना चाहिए (लेकिन इसे अपने ऐप के साथ शिप न करें!)।

इसलिए यदि आपको स्कीमा की जांच करने की आवश्यकता नहीं है और आप चेतावनी से छुटकारा पाना चाहते हैं, तो बस , इस प्रकार 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
इसका वास्तव में क्या मतलब है "अपने ऐप के साथ जहाज न करें"? यह एपीके में शामिल होगा?
जोंगज़ पुंगपुट

2
यदि "अपने ऐप के साथ शिप न करें" का पालन करें, तो क्या मुझे एपीके उत्पन्न करने से पहले जेएसएन फ़ाइलों को हटा देना चाहिए?
भ्रमजाल

8
"अपने ऐप के साथ शिप न करें" का अर्थ है "स्कीम / सेट / कच्ची 'को पसंद करने के लिए स्कीमाकोलेशन सेट न करें। स्कीमा को किसी डायरेक्ट्री में सेट करें जो एपीके में शामिल नहीं है।"
गैल्सीयुरियो

3
@galcyurio $ ProjectDir / स्कीमा एपीके से एक निर्देशिका है, है ना? मैंने उत्पन्न APK का पता लगाया है और मैं इसे वहां नहीं देखता हूं। हालांकि मैं उदाहरण के लिए / res (जो ऐप / src / main / res के लिए खाता हूं) देखता हूं।
xarlymg89

1
@glucaio मैंने एपीके (और ऐप बंडल भी) की खोज की और इसे नहीं पाया। इसलिए मेरा मानना ​​है कि हम सुरक्षित हैं।
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
अगर किसी को आश्चर्य हो रहा है, तो यह सटीक दृष्टिकोण कोप्टिन के
DanielDiSu

1
क्या हमें app/schemasइस ऑपरेशन द्वारा निर्देशिका में उत्पन्न json फाइल को gitignore करना चाहिए । और मैंने सुना है कि हमें स्कीमा को एक निर्देशिका में रखना चाहिए जो इसमें शामिल नहीं है apk। हम वह कैसे कर सकते है?
रवि

2
@ravi उत्पन्न स्कीमा फ़ाइल (ओं) को संस्करण नियंत्रण में संग्रहित किया जाना चाहिए क्योंकि यह परिवर्तन का पता लगाने के लिए कक्ष द्वारा उपयोग किया जाता है और यह सुनिश्चित करने में मदद करता है कि क्या डेटाबेस आप डेटाबेस संस्करण को अपडेट करते हैं और एक प्रवास योजना बनाते हैं
appmattus

1
क्या यह कॉन्फ़िगरेशन रिलीज़ संस्करण को प्रभावित करता है? मेरा मतलब है, जब मैं प्रोजेक्ट को रिलीज़ ऐप पर निर्यात करता हूं।
अनारगु

यदि यह समाधान ईआरआरओआर में परिणत होता है : तर्कों के लिए विधि एनोटेशनप्रोसेसर नहीं मिल सकता है () , नीचे दिए गए लूना के उत्तर की जांच करें: stackoverflow.com/a/54366985/1617737
प्रतिबंध-जियोइंजीनियरिंग

185

Kotlin? ये रहा:

android {

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

    defaultConfig {

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

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

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

//...

प्लगइन के बारे में मत भूलना:

apply plugin: 'kotlin-kapt'

कोटलिन एनोटेशन प्रोसेसर के बारे में अधिक जानकारी के लिए कृपया देखें: कोटलिन डॉक्स


जिस तरह से आपने इसका जवाब दिया: D
theapache64

12

उपरोक्त उत्तर सही हैं। इस संस्करण का पालन करना आसान है:

क्योंकि "स्कीमा निर्यात निर्देशिका एनोटेशन प्रोसेसर को प्रदान नहीं की जाती है", इसलिए हमें स्कीमा निर्यात के लिए निर्देशिका प्रदान करने की आवश्यकता है:

चरण [१] आपकी फाइल में जो रूमडैबस को बढ़ाती है, लाइन को इसमें बदलें:

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

या

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

(क्योंकि डिफ़ॉल्ट मान हमेशा सत्य होता है)

Step [2] अपने build.gradle (प्रोजेक्ट: ????) फ़ाइल में, defaultConfig {} के अंदर (जो कि android {} बड़े सेक्शन के अंदर है ), javaCompileOptions {} सेक्शन को जोड़ें , यह इस तरह होगा:

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

$ प्रोजेक्टडायर : एक चर नाम है, आप इसे बदल नहीं सकते। इसे आपकी खुद की प्रोजेक्ट डायरेक्टरी मिलेगी

स्कीमा : एक स्ट्रिंग है, आप इसे अपनी पसंद के अनुसार बदल सकते हैं। उदाहरण के लिए: "$projectDir/MyOwnSchemas".toString()


चरण में [2], क्या आप सुनिश्चित हैं कि यह है build.gradle(project:????)और नहीं build.gradle(app:????)?
ऐस

9

@mikejonesguy उत्तर एकदम सही है, यदि आप कमरे के माइग्रेशन (अनुशंसित) का परीक्षण करने की योजना बनाते हैं, तो स्रोत सेट में स्कीमा स्थान जोड़ें।

अपनी build.gradle फ़ाइल में आप इन जेनरेट की गई स्कीमा JSON फ़ाइलों को रखने के लिए एक फ़ोल्डर निर्दिष्ट करते हैं। जैसे ही आप अपना स्कीमा अपडेट करते हैं, आप कई JSON फ़ाइलों के साथ समाप्त हो जाएंगे, हर संस्करण के लिए एक। सुनिश्चित करें कि आप हर जेनरेट की गई फ़ाइल को स्रोत नियंत्रण के लिए प्रतिबद्ध करें। अगली बार जब आप अपना संस्करण संख्या फिर से बढ़ाएँगे, तो कक्ष परीक्षण के लिए JSON फ़ाइल का उपयोग करने में सक्षम होगा।

  • फ्लोरिना मुंटेंस्कु ( स्रोत )

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

मैं .ktsग्रैडल फ़ाइलों (कोटलिन ग्रेड डीएसएल) और kotlin-kaptप्लगइन का उपयोग करता हूं लेकिन मुझे अभी भी एक स्क्रिप्ट संकलन त्रुटि मिलती है जब मैं इवानोव मैकसिम के उत्तर का उपयोग करता हूं।

Unresolved reference: kapt

मेरे लिए यह केवल एक चीज थी जो काम करती थी:

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

मेरे लिए कुछ भी काम नहीं कर रहा है। मैं कोटलिन का उपयोग कर रहा हूं।
निकी

0

संभवतः आपने अपने कमरे की कक्षा को बाल RoomDatabaseबाल वर्ग में नहीं जोड़ा था@Database(entities = {your_classes})

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.