กำหนดค่าตัวแปรของบิวด์

หน้านี้แสดงวิธีกำหนดค่าตัวแปรบิลด์เพื่อ สร้างแอปเวอร์ชันต่างๆ จากโปรเจ็กต์เดียว รวมถึงวิธี จัดการการกำหนดค่าการลงนามและการขึ้นต่อกันอย่างเหมาะสม

ตัวแปรบิลด์แต่ละรายการแสดงถึงแอปเวอร์ชันต่างๆ ที่คุณสร้างได้ เช่น คุณอาจต้องการสร้างแอปเวอร์ชันหนึ่ง ที่ให้บริการฟรีพร้อมเนื้อหาแบบจำกัด และอีกเวอร์ชันหนึ่งที่ต้องชำระเงิน ซึ่งมีเนื้อหามากกว่า นอกจากนี้ คุณยังสร้างแอปเวอร์ชันต่างๆ ที่กำหนดเป้าหมายเป็นอุปกรณ์ที่แตกต่างกันได้ โดยอิงตามระดับ API หรืออุปกรณ์อื่นๆ ที่แตกต่างกัน

ตัวแปรบิลด์เป็นผลลัพธ์ที่ได้จาก Gradle ซึ่งใช้ชุดกฎที่เฉพาะเจาะจง เพื่อรวมการตั้งค่า โค้ด และทรัพยากรที่กำหนดค่าไว้ใน ประเภทบิลด์และ Product Flavor แม้ว่าคุณจะไม่ได้กำหนดค่าตัวแปรของบิลด์โดยตรง แต่คุณก็กำหนดค่าประเภทบิลด์และรสชาติของผลิตภัณฑ์ที่ประกอบกันเป็นตัวแปรของบิลด์ได้

ตัวอย่างเช่น Product Flavor "demo" อาจระบุฟีเจอร์บางอย่าง และข้อกำหนดของอุปกรณ์ เช่น ซอร์สโค้ด ทรัพยากร และระดับ API ขั้นต่ำ ในขณะที่ Build Type "debug" จะใช้การตั้งค่าการสร้างและ การแพ็กเกจที่แตกต่างกัน เช่น ตัวเลือกการแก้ไขข้อบกพร่องและคีย์การลงนาม ตัวแปรบิลด์ที่รวมทั้ง 2 อย่างนี้คือแอปเวอร์ชัน "demoDebug" ซึ่งมีการ รวมการกำหนดค่าและทรัพยากรที่รวมอยู่ในรสชาติผลิตภัณฑ์ "demo" ประเภทบิลด์ "debug" และชุดแหล่งที่มา main/

กำหนดค่าประเภทบิลด์

คุณสามารถสร้างและกำหนดค่าประเภทบิลด์ภายในบล็อก android ของไฟล์ build.gradle.kts ระดับโมดูลได้ เมื่อคุณสร้างโมดูลใหม่ Android Studio จะสร้างประเภทบิลด์ดีบักและรีลีสโดยอัตโนมัติ แม้ว่าประเภทบิลด์สำหรับแก้ไขข้อบกพร่องจะไม่ปรากฏในไฟล์การกำหนดค่าบิลด์ แต่ Android Studio จะกำหนดค่าด้วย debuggable true ซึ่งจะช่วยให้คุณแก้ไขข้อบกพร่องของแอปในอุปกรณ์ Android ที่ปลอดภัยและ กำหนดค่า App Signing ด้วยที่เก็บคีย์การแก้ไขข้อบกพร่องทั่วไปได้

คุณเพิ่มประเภทบิลด์การแก้ไขข้อบกพร่องลงในการกำหนดค่าได้หากต้องการเพิ่ม หรือเปลี่ยนการตั้งค่าบางอย่าง ตัวอย่างต่อไปนี้ระบุ applicationIdSuffix สำหรับประเภทบิลด์ดีบัก และกำหนดค่า ประเภทบิลด์ "staging" ที่เริ่มต้นโดยใช้การตั้งค่าจากประเภทบิลด์ดีบัก

Kotlin

android {     defaultConfig {         manifestPlaceholders["hostName"] = "www.example.com"         ...     }     buildTypes {         getByName("release") {             isMinifyEnabled = true             proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")         }          getByName("debug") {             applicationIdSuffix = ".debug"             isDebuggable = true         }          /**          * The `initWith` property lets you copy configurations from other build types,          * then configure only the settings you want to change. This one copies the debug build          * type, and then changes the manifest placeholder and application ID.          */         create("staging") {             initWith(getByName("debug"))             manifestPlaceholders["hostName"] = "internal.example.com"             applicationIdSuffix = ".debugStaging"         }     } }

Groovy

android {     defaultConfig {         manifestPlaceholders = [hostName:"www.example.com"]         ...     }     buildTypes {         release {             minifyEnabled true             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'         }          debug {             applicationIdSuffix ".debug"             debuggable true         }          /**          * The `initWith` property lets you copy configurations from other build types,          * then configure only the settings you want to change. This one copies the debug build          * type, and then changes the manifest placeholder and application ID.          */         staging {             initWith debug             manifestPlaceholders = [hostName:"internal.example.com"]             applicationIdSuffix ".debugStaging"         }     } }

หมายเหตุ: เมื่อทำการเปลี่ยนแปลงไฟล์การกำหนดค่าบิลด์ Android Studio จะกำหนดให้คุณซิงค์โปรเจ็กต์กับการกำหนดค่าใหม่ หากต้องการซิงค์โปรเจ็กต์ ให้คลิกซิงค์เลย ในแถบการแจ้งเตือนที่ปรากฏขึ้นเมื่อคุณทำการเปลี่ยนแปลง หรือคลิก ซิงค์โปรเจ็กต์ จากแถบเครื่องมือ หาก Android Studio พบข้อผิดพลาดในการกำหนดค่า หน้าต่างข้อความจะปรากฏขึ้นเพื่ออธิบายปัญหา

ดูข้อมูลเพิ่มเติมเกี่ยวกับพร็อพเพอร์ตี้ทั้งหมดที่คุณกําหนดค่าได้ด้วยประเภทบิลด์ โปรดอ่านข้อมูลอ้างอิง BuildType

กำหนดค่ารสชาติของผลิตภัณฑ์

การสร้างรสชาติของผลิตภัณฑ์คล้ายกับการสร้างประเภทบิลด์ เพิ่มรสชาติของผลิตภัณฑ์ลงในบล็อก productFlavors ในการกำหนดค่าบิลด์และรวมการตั้งค่าที่ต้องการ Product Flavor รองรับพร็อพเพอร์ตี้เดียวกันกับ defaultConfig เนื่องจาก defaultConfig เป็นของคลาส ProductFlavor ซึ่งหมายความว่าคุณสามารถระบุการกำหนดค่าพื้นฐานสำหรับทุกรสชาติในบล็อก defaultConfig และแต่ละรสชาติสามารถเปลี่ยนค่าเริ่มต้นเหล่านี้ได้ เช่น applicationId หากต้องการ ดูข้อมูลเพิ่มเติมเกี่ยวกับรหัสแอปพลิเคชัน โปรดอ่าน ตั้งค่ารหัสแอปพลิเคชัน

หมายเหตุ: คุณยังคงต้องระบุชื่อแพ็กเกจโดยใช้แอตทริบิวต์ package ในไฟล์ Manifest main/ คุณต้องใช้ชื่อแพ็กเกจนั้นในซอร์สโค้ดเพื่ออ้างอิงถึงคลาส R หรือเพื่อแก้ไข การลงทะเบียนกิจกรรมหรือบริการที่เกี่ยวข้องด้วย ซึ่งจะช่วยให้คุณใช้ applicationId เพื่อให้ผลิตภัณฑ์แต่ละรสชาติมีรหัสที่ไม่ซ้ำกันสำหรับ การบรรจุและการจัดจำหน่ายโดยไม่ต้องเปลี่ยนซอร์สโค้ด

รสชาติทั้งหมดต้องอยู่ในมิติข้อมูลรสชาติที่มีชื่อ ซึ่งเป็นกลุ่มของ รสชาติผลิตภัณฑ์ คุณต้องกำหนดรสชาติทั้งหมดให้กับมิติข้อมูลรสชาติ ไม่เช่นนั้นจะได้รับข้อผิดพลาดในการสร้างต่อไปนี้

   Error: All flavors must now belong to a named flavor dimension.   The flavor 'flavor_name' is not assigned to a flavor dimension. 

หากโมดูลที่ระบุมีมิติข้อมูลรสชาติเพียงรายการเดียว ปลั๊กอิน Android Gradle จะกำหนดรสชาติทั้งหมดของโมดูลให้กับมิติข้อมูลนั้นโดยอัตโนมัติ

ตัวอย่างโค้ดต่อไปนี้สร้างมิติข้อมูลรสชาติชื่อ "version" และเพิ่มรสชาติผลิตภัณฑ์ "demo" และ "full" โดยแต่ละรสชาติจะมี applicationIdSuffix และ versionNameSuffix ของตัวเอง

Kotlin

android {     ...     defaultConfig {...}     buildTypes {         getByName("debug"){...}         getByName("release"){...}     }     // Specifies one flavor dimension.     flavorDimensions += "version"     productFlavors {         create("demo") {             // Assigns this product flavor to the "version" flavor dimension.             // If you are using only one dimension, this property is optional,             // and the plugin automatically assigns all the module's flavors to             // that dimension.             dimension = "version"             applicationIdSuffix = ".demo"             versionNameSuffix = "-demo"         }         create("full") {             dimension = "version"             applicationIdSuffix = ".full"             versionNameSuffix = "-full"         }     } }

Groovy

android {     ...     defaultConfig {...}     buildTypes {         debug{...}         release{...}     }     // Specifies one flavor dimension.     flavorDimensions "version"     productFlavors {         demo {             // Assigns this product flavor to the "version" flavor dimension.             // If you are using only one dimension, this property is optional,             // and the plugin automatically assigns all the module's flavors to             // that dimension.             dimension "version"             applicationIdSuffix ".demo"             versionNameSuffix "-demo"         }         full {             dimension "version"             applicationIdSuffix ".full"             versionNameSuffix "-full"         }     } }

หมายเหตุ: หากคุณมีแอปเวอร์ชันเดิม (สร้างก่อนเดือนสิงหาคม 2021) ที่จัดจำหน่ายโดยใช้ APK ใน Google Play หากต้องการจัดจำหน่ายแอปโดยใช้การรองรับ APK หลายรายการใน Google Play ให้กำหนดapplicationIdค่าเดียวกัน ให้กับตัวแปรทั้งหมด และกำหนดversionCode ที่แตกต่างกันให้กับตัวแปรแต่ละรายการ หากต้องการเผยแพร่แอปเวอร์ชันต่างๆ เป็นแอปแยกกันใน Google Play คุณต้องกำหนด applicationId ที่แตกต่างกันให้กับแต่ละเวอร์ชัน

หลังจากสร้างและกำหนดค่าผลิตภัณฑ์แล้ว ให้คลิกซิงค์ เลยในแถบการแจ้งเตือน เมื่อการซิงค์เสร็จสมบูรณ์แล้ว Gradle จะสร้างตัวแปรบิลด์โดยอัตโนมัติตามประเภทบิลด์และรสชาติผลิตภัณฑ์ และตั้งชื่อตาม<product-flavor><Build-Type> ตัวอย่างเช่น หากคุณ สร้างรสชาติผลิตภัณฑ์ "demo" และ "full" และเก็บค่าเริ่มต้น "debug" และ ประเภทบิลด์ "release" ไว้ Gradle จะสร้างตัวแปรบิลด์ต่อไปนี้

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

หากต้องการเลือกตัวแปรบิลด์ที่จะสร้างและ เรียกใช้ ให้ไปที่บิลด์ > เลือกตัวแปรบิลด์ แล้วเลือก ตัวแปรบิลด์จากเมนู หากต้องการเริ่มปรับแต่งตัวแปรบิลด์แต่ละรายการด้วยฟีเจอร์และ ทรัพยากรของตัวเอง คุณจะต้องสร้างและจัดการชุดแหล่งที่มาตามที่อธิบายไว้ในหน้านี้

เปลี่ยนรหัสแอปพลิเคชันสำหรับตัวแปรบิลด์

เมื่อคุณสร้าง APK หรือ AAB สำหรับแอป เครื่องมือบิลด์จะติดแท็กแอปด้วย รหัสแอปพลิเคชันที่กำหนดไว้ในบล็อก defaultConfig จากไฟล์ build.gradle.kts ดังที่แสดงในตัวอย่างต่อไปนี้ อย่างไรก็ตาม หากต้องการสร้างแอปเวอร์ชันต่างๆ ให้ปรากฏเป็นข้อมูลแยกกันใน Google Play Store เช่น เวอร์ชัน "ฟรี" และ "โปร" คุณจะต้องสร้างตัวแปรบิลด์แยกกันซึ่งแต่ละตัวแปรจะมีรหัสแอปพลิเคชันที่แตกต่างกัน

ในกรณีนี้ ให้กำหนดแต่ละรุ่นเป็นรสชาติของผลิตภัณฑ์แยกกัน สำหรับแต่ละรสชาติ ภายในบล็อก productFlavors คุณสามารถกำหนดพร็อพเพอร์ตี้ applicationId ใหม่ หรือจะต่อท้ายกลุ่มกับรหัสแอปพลิเคชันเริ่มต้น โดยใช้ applicationIdSuffix แทนก็ได้ ดังที่แสดงที่นี่

Kotlin

android {     defaultConfig {         applicationId = "com.example.myapp"     }     productFlavors {         create("free") {             applicationIdSuffix = ".free"         }         create("pro") {             applicationIdSuffix = ".pro"         }     } }

Groovy

android {     defaultConfig {         applicationId "com.example.myapp"     }     productFlavors {         free {             applicationIdSuffix ".free"         }         pro {             applicationIdSuffix ".pro"         }     } }

ด้วยวิธีนี้ รหัสแอปพลิเคชันสำหรับผลิตภัณฑ์เวอร์ชัน "ฟรี" จะเป็น "com.example.myapp.free"

นอกจากนี้ คุณยังใช้ applicationIdSuffix เพื่อต่อท้ายกลุ่มตามประเภทบิลด์ได้ด้วย ดังที่แสดงที่นี่

Kotlin

android {     ...     buildTypes {         getByName("debug") {             applicationIdSuffix = ".debug"         }     } }

Groovy

android {     ...     buildTypes {         debug {             applicationIdSuffix ".debug"         }     } }

เนื่องจาก Gradle ใช้การกำหนดค่าประเภทบิลด์หลังจาก Product Flavor รหัสแอปพลิเคชันสำหรับตัวแปรบิลด์ "free debug" คือ "com.example.myapp.free.debug" ซึ่งจะมีประโยชน์เมื่อคุณต้องการมีทั้ง บิลด์การแก้ไขข้อบกพร่องและบิลด์ที่เผยแพร่ในอุปกรณ์เดียวกัน เนื่องจากแอป 2 แอปไม่สามารถมี รหัสแอปพลิเคชันเดียวกันได้

หากคุณมีแอปเวอร์ชันเดิม (สร้างขึ้นก่อนเดือนสิงหาคม 2021) ที่เผยแพร่โดยใช้ APK ใน Google Play และต้องการใช้ข้อมูลแอปเดียวกันเพื่อเผยแพร่ APK หลายรายการที่แต่ละรายการกำหนดเป้าหมายเป็นการกำหนดค่าอุปกรณ์ที่แตกต่างกัน เช่น ระดับ API คุณต้องใช้รหัสแอปพลิเคชันเดียวกันสำหรับตัวแปรบิลด์แต่ละรายการ แต่ต้องกำหนด versionCode ที่แตกต่างกันให้กับ APK แต่ละรายการ ดูข้อมูลเพิ่มเติมได้ที่หัวข้อการรองรับ APK หลายรายการ การเผยแพร่โดยใช้ AAB จะไม่ได้รับผลกระทบ เนื่องจากใช้ Artifact เดียวที่ใช้รหัสเวอร์ชันและรหัสแอปพลิเคชันเดียวโดยค่าเริ่มต้น

เคล็ดลับ: หากต้องการอ้างอิงรหัสแอปพลิเคชันในไฟล์ ไฟล์ Manifest คุณสามารถใช้ตัวยึดตำแหน่ง ${applicationId} ในแอตทริบิวต์ Manifest ใดก็ได้ ในระหว่างการสร้าง Gradle จะแทนที่แท็กนี้ด้วย รหัสแอปพลิเคชันจริง ดูข้อมูลเพิ่มเติมได้ที่แทรกตัวแปรบิลด์ ลงในไฟล์ Manifest

รวมผลิตภัณฑ์หลายรสชาติเข้ากับมิติข้อมูลรสชาติ

ในบางกรณี คุณอาจต้องการรวมการกำหนดค่าจากผลิตภัณฑ์หลายเวอร์ชัน เช่น คุณอาจต้องการสร้างการกำหนดค่าที่แตกต่างกันสำหรับ Product Flavor "full" และ "demo" ที่อิงตามระดับ API โดยปลั๊กอิน Android Gradle จะช่วยให้คุณสร้างกลุ่ม Product Flavor หลายกลุ่มเป็นมิติข้อมูล Flavor ได้

เมื่อสร้างแอป Gradle จะรวมการกำหนดค่า Product Flavor จากมิติข้อมูล Flavor แต่ละรายการที่คุณกำหนดไว้กับการกำหนดค่าประเภทบิลด์เพื่อสร้างตัวแปรบิลด์สุดท้าย Gradle จะไม่รวม Product Flavor ที่อยู่ใน Flavor Dimension เดียวกัน

ตัวอย่างโค้ดต่อไปนี้ใช้พร็อพเพอร์ตี้ flavorDimensions เพื่อสร้างมิติข้อมูล "โหมด" เพื่อจัดกลุ่มรสชาติผลิตภัณฑ์ "เต็ม" และ "เดโม" และมิติข้อมูลรสชาติ "api" เพื่อจัดกลุ่มการกำหนดค่ารสชาติผลิตภัณฑ์ตามระดับ API

Kotlin

android {   ...   buildTypes {     getByName("debug") {...}     getByName("release") {...}   }    // Specifies the flavor dimensions you want to use. The order in which you   // list the dimensions determines their priority, from highest to lowest,   // when Gradle merges variant sources and configurations. You must assign   // each product flavor you configure to one of the flavor dimensions.   flavorDimensions += listOf("api", "mode")    productFlavors {     create("demo") {       // Assigns this product flavor to the "mode" flavor dimension.       dimension = "mode"       ...     }      create("full") {       dimension = "mode"       ...     }      // Configurations in the "api" product flavors override those in "mode"     // flavors and the defaultConfig block. Gradle determines the priority     // between flavor dimensions based on the order in which they appear next     // to the flavorDimensions property, with the first dimension having a higher     // priority than the second, and so on.     create("minApi24") {       dimension = "api"       minSdk = 24       // To ensure the target device receives the version of the app with       // the highest compatible API level, assign version codes in increasing       // value with API level.       versionCode = 30000 + (android.defaultConfig.versionCode ?: 0)       versionNameSuffix = "-minApi24"       ...     }      create("minApi23") {       dimension = "api"       minSdk = 23       versionCode = 20000  + (android.defaultConfig.versionCode ?: 0)       versionNameSuffix = "-minApi23"       ...     }      create("minApi21") {       dimension = "api"       minSdk = 21       versionCode = 10000  + (android.defaultConfig.versionCode ?: 0)       versionNameSuffix = "-minApi21"       ...     }   } } ...

Groovy

android {   ...   buildTypes {     debug {...}     release {...}   }    // Specifies the flavor dimensions you want to use. The order in which you   // list the dimensions determines their priority, from highest to lowest,   // when Gradle merges variant sources and configurations. You must assign   // each product flavor you configure to one of the flavor dimensions.   flavorDimensions "api", "mode"    productFlavors {     demo {       // Assigns this product flavor to the "mode" flavor dimension.       dimension "mode"       ...     }      full {       dimension "mode"       ...     }      // Configurations in the "api" product flavors override those in "mode"     // flavors and the defaultConfig block. Gradle determines the priority     // between flavor dimensions based on the order in which they appear next     // to the flavorDimensions property, with the first dimension having a higher     // priority than the second, and so on.     minApi24 {       dimension "api"       minSdkVersion 24       // To ensure the target device receives the version of the app with       // the highest compatible API level, assign version codes in increasing       // value with API level.        versionCode 30000 + android.defaultConfig.versionCode       versionNameSuffix "-minApi24"       ...     }      minApi23 {       dimension "api"       minSdkVersion 23       versionCode 20000  + android.defaultConfig.versionCode       versionNameSuffix "-minApi23"       ...     }      minApi21 {       dimension "api"       minSdkVersion 21       versionCode 10000  + android.defaultConfig.versionCode       versionNameSuffix "-minApi21"       ...     }   } } ...

จำนวนตัวแปรบิลด์ที่ Gradle สร้างจะเท่ากับผลคูณของ จำนวนรสชาติในมิติรสชาติแต่ละมิติและจำนวนประเภทบิลด์ที่คุณ กำหนดค่า เมื่อ Gradle ตั้งชื่อตัวแปรบิลด์แต่ละรายการหรืออาร์ติแฟกต์ที่เกี่ยวข้อง รสชาติของผลิตภัณฑ์ ที่อยู่ในมิติข้อมูลรสชาติที่มีลำดับความสำคัญสูงกว่าจะปรากฏก่อน ตามด้วย รสชาติจากมิติข้อมูลที่มีลำดับความสำคัญต่ำกว่า และตามด้วยประเภทบิลด์

เมื่อใช้การกำหนดค่าบิลด์ก่อนหน้าเป็นตัวอย่าง Gradle จะสร้างตัวแปรบิลด์ทั้งหมด 12 รายการโดยใช้รูปแบบการตั้งชื่อต่อไปนี้

  • ตัวแปรบิลด์: [minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
  • APK ที่เกี่ยวข้อง: app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
  • ตัวอย่างเช่น
    ตัวแปรบิลด์: minApi24DemoDebug
    APK ที่เกี่ยวข้อง: app-minApi24-demo-debug.apk

นอกเหนือจากไดเรกทอรีชุดแหล่งที่มาที่คุณสร้างสำหรับแต่ละ รสชาติของผลิตภัณฑ์และตัวแปรบิลด์แล้ว คุณยังสร้างไดเรกทอรีชุดแหล่งที่มา สำหรับชุดค่าผสมแต่ละชุดของรสชาติของผลิตภัณฑ์ได้ด้วย เช่น คุณสร้าง และเพิ่มแหล่งที่มาของ Java ไปยังไดเรกทอรี src/demoMinApi24/java/ ได้ และ Gradle จะใช้แหล่งที่มาเหล่านั้นเฉพาะเมื่อสร้างตัวแปรที่รวม รสชาติของผลิตภัณฑ์ทั้ง 2 รายการนั้น

ชุดแหล่งข้อมูลที่คุณสร้างขึ้นสำหรับชุดค่าผสมรสชาติของผลิตภัณฑ์ จะมีลำดับความสำคัญสูงกว่าชุดแหล่งข้อมูลที่อยู่ในรสชาติของผลิตภัณฑ์แต่ละรายการ ดูข้อมูลเพิ่มเติมเกี่ยวกับชุดแหล่งที่มาและวิธีที่ Gradle ผสานรวมทรัพยากรได้ที่ส่วนเกี่ยวกับวิธีสร้าง ชุดแหล่งที่มา

กรองตัวแปร

Gradle จะสร้างตัวแปรบิลด์สำหรับชุดค่าผสมที่เป็นไปได้ทั้งหมดของ Product Flavors และประเภทบิลด์ที่คุณกำหนดค่า อย่างไรก็ตาม อาจมี ตัวแปรบิลด์บางรายการที่คุณไม่ต้องการหรือไม่มีประโยชน์ใน บริบทของโปรเจ็กต์ หากต้องการนำการกำหนดค่าตัวแปรบิลด์บางรายการออก ให้สร้างตัวกรองตัวแปรในไฟล์ build.gradle.kts ระดับโมดูล

ใช้การกำหนดค่าบิลด์จากส่วนก่อนหน้าเป็นตัวอย่าง สมมติว่าคุณวางแผนที่จะรองรับเฉพาะระดับ API 23 ขึ้นไปสำหรับเวอร์ชัน สาธิตของแอป คุณสามารถใช้บล็อก variantFilter เพื่อกรองการกำหนดค่าตัวแปรบิลด์ทั้งหมด ที่รวมรสชาติผลิตภัณฑ์ "minApi21" และ "demo" ได้ดังนี้

Kotlin

android {   ...   buildTypes {...}    flavorDimensions += listOf("api", "mode")   productFlavors {     create("demo") {...}     create("full") {...}     create("minApi24") {...}     create("minApi23") {...}     create("minApi21") {...}   } }  androidComponents {     beforeVariants { variantBuilder ->         // To check for a certain build type, use variantBuilder.buildType == "<buildType>"         if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {             // Gradle ignores any variants that satisfy the conditions above.             variantBuilder.enable = false         }     } } ...

Groovy

android {   ...   buildTypes {...}    flavorDimensions "api", "mode"   productFlavors {     demo {...}     full {...}     minApi24 {...}     minApi23 {...}     minApi21 {...}   }    variantFilter { variant ->       def names = variant.flavors*.name       // To check for a certain build type, use variant.buildType.name == "<buildType>"       if (names.contains("minApi21") && names.contains("demo")) {           // Gradle ignores any variants that satisfy the conditions above.           setIgnore(true)       }   } } ...

เมื่อเพิ่มตัวกรองตัวแปรในการกำหนดค่าบิลด์แล้วคลิกซิงค์ ตอนนี้ในแถบการแจ้งเตือน Gradle จะไม่สนใจตัวแปรบิลด์ใดๆ ที่ตรงกับ เงื่อนไขที่คุณระบุ ตัวแปรบิลด์จะไม่ปรากฏในเมนูอีกต่อไป เมื่อคุณคลิกบิลด์ > เลือกตัวแปรบิลด์จากแถบเมนู หรือตัวแปรบิลด์ ใน แถบหน้าต่างเครื่องมือ

สร้างชุดแหล่งที่มา

โดยค่าเริ่มต้น Android Studio จะสร้างmain/ ชุดแหล่งที่มาและไดเรกทอรีสำหรับ ทุกอย่างที่คุณต้องการแชร์ระหว่างตัวแปรบิลด์ทั้งหมด อย่างไรก็ตาม คุณ สามารถสร้างชุดแหล่งที่มาใหม่เพื่อควบคุมว่า Gradle จะคอมไพล์และ แพ็กเกจไฟล์ใดสำหรับประเภทบิลด์ รสชาติของผลิตภัณฑ์ ชุดค่าผสมของ รสชาติของผลิตภัณฑ์ (เมื่อใช้มิติข้อมูลรสชาติ) และตัวแปรบิลด์

เช่น คุณสามารถกำหนดฟังก์ชันพื้นฐานในmain/ชุดแหล่งที่มาและใช้ชุดแหล่งที่มาของ Product Flavor เพื่อเปลี่ยนการสร้างแบรนด์ของแอปสำหรับไคลเอ็นต์ต่างๆ หรือ รวมสิทธิ์พิเศษและฟังก์ชันการบันทึกเฉพาะสำหรับตัวแปรบิลด์ ที่ใช้ประเภทบิลด์ดีบัก

Gradle คาดหวังให้จัดระเบียบไฟล์และไดเรกทอรีของชุดแหล่งที่มาในลักษณะหนึ่ง ซึ่งคล้ายกับชุดแหล่งที่มาของ main/ ตัวอย่างเช่น Gradle คาดหวังให้ไฟล์คลาส Kotlin หรือ Java ที่เฉพาะเจาะจงกับประเภทบิลด์ "debug" อยู่ใน ไดเรกทอรี src/debug/kotlin/ หรือ src/debug/java/

ปลั๊กอิน Android Gradle มีงาน Gradle ที่มีประโยชน์ซึ่งจะแสดงวิธีจัดระเบียบไฟล์สำหรับประเภทบิลด์ รสชาติของผลิตภัณฑ์ และตัวแปรบิลด์แต่ละรายการ ตัวอย่างเช่น ตัวอย่างต่อไปนี้จากเอาต์พุตของงาน อธิบายตำแหน่งที่ Gradle คาดว่าจะพบไฟล์บางอย่างสำหรับบิลด์ประเภท "debug"

 ------------------------------------------------------------ Project :app ------------------------------------------------------------  ...  debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources] 

หากต้องการดูเอาต์พุตนี้ ให้ทำตามขั้นตอนต่อไปนี้

  1. คลิก Gradle ในแถบหน้าต่างเครื่องมือ
  2. ไปที่ MyApplication > Tasks > android แล้ว ดับเบิลคลิก sourceSets

    หากต้องการดูโฟลเดอร์ Tasks คุณต้องอนุญาตให้ Gradle สร้างรายการงาน ระหว่างการซิงค์ โดยทำตามขั้นตอนต่อไปนี้

    1. คลิกไฟล์ > การตั้งค่า > ทดลอง (Android Studio > การตั้งค่า > ทดลอง ใน macOS)
    2. ยกเลิกการเลือกไม่ต้อง สร้างรายการงาน Gradle ระหว่างการซิงค์ Gradle
  3. หลังจาก Gradle ดำเนินการในงานแล้ว หน้าต่างเรียกใช้จะเปิดขึ้นเพื่อแสดงเอาต์พุต

หมายเหตุ: เอาต์พุตของงานยังแสดงวิธีจัดระเบียบชุดแหล่งที่มา สำหรับไฟล์ที่คุณต้องการใช้เพื่อเรียกใช้การทดสอบสำหรับแอป เช่น test/ และ androidTest/ ชุดแหล่งที่มาสำหรับการทดสอบ

เมื่อสร้างตัวแปรบิลด์ใหม่ Android Studio จะไม่สร้างไดเรกทอรีชุดแหล่งที่มาให้ แต่จะมีตัวเลือก 2-3 อย่างที่จะช่วยคุณได้ เช่น หากต้องการสร้างเฉพาะไดเรกทอรี java/ สำหรับประเภทบิลด์ "debug" ให้ทำดังนี้

  1. เปิดแผงโปรเจ็กต์ แล้วเลือกมุมมองโปรเจ็กต์จากเมนูที่ด้านบนของแผง
  2. ไปที่ MyProject/app/src/
  3. คลิกขวาที่ไดเรกทอรี src แล้วเลือก New > Directory
  4. จากเมนูในส่วนชุดแหล่งที่มาของ Gradle ให้เลือก full/java
  5. กด Enter

Android Studio จะสร้างไดเรกทอรีชุดแหล่งที่มาสำหรับประเภทบิลด์การแก้ไขข้อบกพร่อง และ จากนั้นจะสร้างไดเรกทอรี java/ ภายใน หรือ Android Studio จะสร้างไดเรกทอรีให้คุณเมื่อเพิ่มไฟล์ใหม่ลงใน โปรเจ็กต์สำหรับตัวแปรบิลด์ที่เฉพาะเจาะจง

เช่น หากต้องการสร้างไฟล์ XML ของค่าสำหรับประเภทบิลด์ "debug" ให้ทำดังนี้

  1. ในแผงโปรเจ็กต์ ให้คลิกขวาที่ไดเรกทอรี src แล้วเลือกใหม่ > XML > ไฟล์ XML ของค่า
  2. ป้อนชื่อไฟล์ XML หรือใช้ชื่อเริ่มต้น
  3. จากเมนูข้างชุดแหล่งข้อมูลเป้าหมาย ให้เลือก debug
  4. คลิกเสร็จสิ้น

เนื่องจากมีการระบุประเภทบิลด์ "debug" เป็นชุดแหล่งที่มาเป้าหมาย Android Studio จึงสร้างไดเรกทอรีที่จำเป็นโดยอัตโนมัติเมื่อสร้างไฟล์ XML โครงสร้างไดเรกทอรีที่ได้จะมีลักษณะดังรูปที่ 1

รูปที่ 1 ไดเรกทอรีชุดแหล่งที่มาใหม่สำหรับการสร้างประเภท "debug"

ชุดแหล่งที่มาที่ใช้งานอยู่จะมีสัญญาณบอกสถานะสีเขียวในไอคอนเพื่อแสดงว่าชุดดังกล่าวใช้งานอยู่ debug ชุดแหล่งข้อมูลจะต่อท้ายด้วย [main] เพื่อแสดงว่าระบบจะผสานชุดแหล่งข้อมูลนี้ เข้ากับชุดแหล่งข้อมูล main

คุณยังสร้างไดเรกทอรีชุดแหล่งที่มาสำหรับ รสชาติของผลิตภัณฑ์ เช่น src/demo/ และสร้างตัวแปร เช่น src/demoDebug/ ได้ด้วยขั้นตอนเดียวกัน นอกจากนี้ คุณยังสร้างชุดแหล่งข้อมูลการทดสอบ ที่กำหนดเป้าหมายไปยังตัวแปรบิลด์ที่เฉพาะเจาะจงได้ด้วย เช่น src/androidTestDemoDebug/ ดูข้อมูลเพิ่มเติมได้ที่หัวข้อเกี่ยวกับ การทดสอบชุดแหล่งที่มา

เปลี่ยนการกำหนดค่าชุดแหล่งข้อมูลเริ่มต้น

หากมีแหล่งที่มาที่ไม่ได้จัดระเบียบเป็นโครงสร้างไฟล์ชุดแหล่งที่มาเริ่มต้น ที่ Gradle คาดหวัง ดังที่อธิบายไว้ในส่วนก่อนหน้าเกี่ยวกับ การสร้างชุดแหล่งที่มา คุณสามารถใช้บล็อก sourceSets เพื่อเปลี่ยนตำแหน่งที่ Gradle ค้นหาเพื่อรวบรวม ไฟล์สำหรับแต่ละคอมโพเนนต์ของชุดแหล่งที่มา

บล็อก sourceSets ต้องอยู่ในบล็อก android คุณไม่จำเป็นต้องย้ายไฟล์ต้นฉบับ เพียงแค่ระบุเส้นทางที่สัมพันธ์กับไฟล์ build.gradle.kts ระดับโมดูลให้ Gradle เพื่อให้ Gradle ค้นหาไฟล์สำหรับคอมโพเนนต์แต่ละชุดแหล่งที่มาได้ ดูว่าคุณกำหนดค่าคอมโพเนนต์ใดได้บ้างและจะแมปคอมโพเนนต์กับไฟล์หรือไดเรกทอรีหลายรายการได้หรือไม่ที่เอกสารอ้างอิง API ของปลั๊กอิน Android Gradle

ตัวอย่างโค้ดต่อไปนี้จะแมปแหล่งที่มาจากไดเรกทอรี app/other/ ไปยังคอมโพเนนต์บางอย่างของชุดแหล่งที่มา main และเปลี่ยน ไดเรกทอรีรากของชุดแหล่งที่มา androidTest

Kotlin

android {   ...   // Encapsulates configurations for the main source set.   sourceSets.getByName("main") {     // Changes the directory for Java sources. The default directory is     // 'src/main/java'.     java.setSrcDirs(listOf("other/java"))      // If you list multiple directories, Gradle uses all of them to collect     // sources. Because Gradle gives these directories equal priority, if     // you define the same resource in more than one directory, you receive an     // error when merging resources. The default directory is 'src/main/res'.     res.setSrcDirs(listOf("other/res1", "other/res2"))      // Note: Avoid specifying a directory that is a parent to one     // or more other directories you specify. For example, avoid the following:     // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']     // Specify either only the root 'other/res1' directory or only the     // nested 'other/res1/layouts' and 'other/res1/strings' directories.      // For each source set, you can specify only one Android manifest.     // By default, Android Studio creates a manifest for your main source     // set in the src/main/ directory.     manifest.srcFile("other/AndroidManifest.xml")     ...   }    // Create additional blocks to configure other source sets.   sourceSets.getByName("androidTest") {       // If all the files for a source set are located under a single root       // directory, you can specify that directory using the setRoot property.       // When gathering sources for the source set, Gradle looks only in locations       // relative to the root directory you specify. For example, after applying the       // configuration below for the androidTest source set, Gradle looks for Java       // sources only in the src/tests/java/ directory.       setRoot("src/tests")       ...   } } ...

Groovy

android {   ...   sourceSets {     // Encapsulates configurations for the main source set.     main {       // Changes the directory for Java sources. The default directory is       // 'src/main/java'.       java.srcDirs = ['other/java']        // If you list multiple directories, Gradle uses all of them to collect       // sources. Because Gradle gives these directories equal priority, if       // you define the same resource in more than one directory, you receive an       // error when merging resources. The default directory is 'src/main/res'.       res.srcDirs = ['other/res1', 'other/res2']        // Note: Avoid specifying a directory that is a parent to one       // or more other directories you specify. For example, avoid the following:       // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']       // Specify either only the root 'other/res1' directory or only the       // nested 'other/res1/layouts' and 'other/res1/strings' directories.        // For each source set, you can specify only one Android manifest.       // By default, Android Studio creates a manifest for your main source       // set in the src/main/ directory.       manifest.srcFile 'other/AndroidManifest.xml'       ...     }      // Create additional blocks to configure other source sets.     androidTest {        // If all the files for a source set are located under a single root       // directory, you can specify that directory using the setRoot property.       // When gathering sources for the source set, Gradle looks only in locations       // relative to the root directory you specify. For example, after applying the       // configuration below for the androidTest source set, Gradle looks for Java       // sources only in the src/tests/java/ directory.       setRoot 'src/tests'       ...     }   } } ...

โปรดทราบว่าไดเรกทอรีแหล่งที่มาจะเป็นของชุดแหล่งที่มาได้เพียงชุดเดียวเท่านั้น เช่น คุณแชร์แหล่งที่มาของการทดสอบเดียวกันกับทั้งชุดแหล่งที่มา test และ androidTest ไม่ได้ เนื่องจาก Android Studio จะสร้างโมดูล IntelliJ แยกต่างหากสำหรับแต่ละชุดแหล่งที่มาและไม่รองรับรูทเนื้อหาที่ซ้ำกันในชุดแหล่งที่มา

สร้างด้วยชุดแหล่งที่มา

คุณใช้ไดเรกทอรีชุดแหล่งที่มาเพื่อเก็บโค้ดและทรัพยากรที่ต้องการ แพ็กเกจเฉพาะการกำหนดค่าบางอย่างได้ ตัวอย่างเช่น หากคุณกำลังสร้างตัวแปรบิลด์ "demoDebug" ซึ่งเป็นผลิตภัณฑ์ข้ามผลิตภัณฑ์ของรสชาติผลิตภัณฑ์ "demo" และประเภทบิลด์ "debug" Gradle จะดูไดเรกทอรีเหล่านี้และกำหนดลำดับความสำคัญต่อไปนี้

  1. src/demoDebug/ (ชุดแหล่งที่มาของตัวแปรบิลด์)
  2. src/debug/ (ชุดแหล่งที่มาของประเภทบิลด์)
  3. src/demo/ (ชุดแหล่งที่มาของเวอร์ชันผลิตภัณฑ์)
  4. src/main/ (ชุดแหล่งข้อมูลหลัก)

ชุดแหล่งข้อมูลที่สร้างขึ้นสำหรับชุดค่าผสมของรสชาติผลิตภัณฑ์ต้องมีมิติข้อมูลรสชาติทั้งหมด เช่น ชุดแหล่งที่มาของตัวแปรบิลด์ต้องเป็นการรวมกันของประเภทบิลด์และมิติข้อมูลรสชาติทั้งหมด ระบบไม่รองรับการผสานโค้ดและทรัพยากรที่เกี่ยวข้องกับโฟลเดอร์ซึ่งครอบคลุมมิติข้อมูลรสชาติหลายรายการแต่ไม่ใช่ทั้งหมด

หากรวมรสชาติของผลิตภัณฑ์หลายรายการ ระบบจะกำหนดลำดับความสำคัญระหว่างรสชาติของผลิตภัณฑ์ตามมิติข้อมูลรสชาติ ที่รสชาติเหล่านั้นสังกัดอยู่ เมื่อแสดงมิติข้อมูลรสชาติด้วยพร็อพเพอร์ตี้ android.flavorDimensions รสชาติของผลิตภัณฑ์ที่ อยู่ในมิติข้อมูลรสชาติแรกที่คุณแสดงจะมีลำดับความสำคัญสูงกว่า รสชาติที่อยู่ในมิติข้อมูลรสชาติที่สอง และอื่นๆ นอกจากนี้ ชุดแหล่งข้อมูลที่คุณสร้างขึ้นสำหรับชุดค่าผสมของรสชาติผลิตภัณฑ์จะมีลำดับความสำคัญสูงกว่า ชุดแหล่งข้อมูลที่เป็นของรสชาติผลิตภัณฑ์แต่ละรายการ

ลำดับความสำคัญจะเป็นตัวกำหนดว่าชุดแหล่งข้อมูลใดมีลำดับความสำคัญสูงกว่า เมื่อ Gradle รวมโค้ดและทรัพยากร เนื่องจากไดเรกทอรีชุดแหล่งที่มา demoDebug/ น่าจะมีไฟล์ที่เฉพาะเจาะจงกับตัวแปรบิลด์นั้น หาก demoDebug/ มีไฟล์ที่กำหนดไว้ใน debug/ ด้วย Gradle จะใช้ไฟล์ในชุดแหล่งที่มา demoDebug/ ในทำนองเดียวกัน Gradle จะให้ลำดับความสำคัญแก่ไฟล์ในแหล่งที่มาของประเภทบิลด์และ Product Flavor สูงกว่าไฟล์เดียวกันใน main/ Gradle จะพิจารณาลำดับความสำคัญนี้เมื่อใช้กฎการสร้างต่อไปนี้

  • ระบบจะคอมไพล์ซอร์สโค้ดทั้งหมดในไดเรกทอรี kotlin/ หรือ java/ ร่วมกันเพื่อสร้างเอาต์พุตเดียว

    หมายเหตุ: สำหรับตัวแปรบิลด์ที่กำหนด Gradle จะแสดงข้อผิดพลาดในการบิลด์ หากพบไดเรกทอรีชุดแหล่งข้อมูลอย่างน้อย 2 รายการที่กำหนด คลาส Kotlin หรือ Java เดียวกัน เช่น เมื่อสร้างแอปสำหรับแก้ไขข้อบกพร่อง คุณจะ กำหนดทั้ง src/debug/Utility.kt และ src/main/Utility.kt ไม่ได้ เนื่องจาก Gradle จะดูทั้ง ไดเรกทอรีเหล่านี้ในระหว่างกระบวนการบิลด์และแสดงข้อผิดพลาด "คลาสซ้ำ" หากต้องการใช้ Utility.kt เวอร์ชันอื่นสำหรับ ประเภทบิลด์ที่ต่างกัน ประเภทบิลด์แต่ละประเภทต้องกำหนดเวอร์ชันของ ไฟล์ของตัวเอง และไม่รวมไว้ในชุดแหล่งที่มาของ main/

  • ระบบจะผสานไฟล์ Manifest เข้าด้วยกันเป็นไฟล์ Manifest เดียว ระบบจะให้ความสำคัญ ตามลำดับเดียวกับรายการในตัวอย่างก่อนหน้า กล่าวคือ การตั้งค่าไฟล์ Manifest สำหรับประเภทบิลด์ จะลบล้างการตั้งค่าไฟล์ Manifest สำหรับ Product Flavor และอื่นๆ ดูข้อมูลเพิ่มเติมได้ที่การผสานไฟล์ Manifest
  • ระบบจะผสานไฟล์ในไดเรกทอรี values/ เข้าด้วยกัน หากไฟล์ 2 ไฟล์มีชื่อเดียวกัน เช่น ไฟล์ 2 ไฟล์ strings.xml ระบบจะให้ลำดับความสำคัญตามลำดับเดียวกับ รายการในตัวอย่างก่อนหน้า กล่าวคือ ค่าที่กำหนดไว้ในไฟล์ในชุดแหล่งที่มาของประเภทบิลด์ จะลบล้างค่าที่กำหนดไว้ในไฟล์เดียวกันใน Product Flavor และอื่นๆ
  • ระบบจะแพ็กเกจทรัพยากรในไดเรกทอรี res/ และ asset/ ไว้ด้วยกัน หากมีทรัพยากรที่มีชื่อเดียวกันซึ่งกำหนดไว้ใน ชุดแหล่งที่มา 2 ชุดขึ้นไป ระบบจะให้ลำดับความสำคัญตามลำดับเดียวกับรายการ ในตัวอย่างก่อนหน้า
  • Gradle จะให้ความสำคัญกับทรัพยากรและไฟล์ Manifest ที่รวมอยู่ในทรัพยากร Dependency ของโมดูลไลบรารีต่ำสุดเมื่อสร้างแอป

ประกาศทรัพยากร Dependency

หากต้องการกําหนดค่าการขึ้นต่อกันสําหรับตัวแปรบิลด์หรือชุดแหล่งที่มาของการทดสอบที่เฉพาะเจาะจง ให้ใส่คํานําหน้าชื่อตัวแปรบิลด์หรือชุดแหล่งที่มาของการทดสอบก่อนคีย์เวิร์ด Implementation ดังที่แสดงในตัวอย่างต่อไปนี้

Kotlin

dependencies {     // Adds the local "mylibrary" module as a dependency to the "free" flavor.     "freeImplementation"(project(":mylibrary"))      // Adds a remote binary dependency only for local tests.     testImplementation("junit:junit:4.12")      // Adds a remote binary dependency only for the instrumented test APK.     androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }

Groovy

dependencies {     // Adds the local "mylibrary" module as a dependency to the "free" flavor.     freeImplementation project(":mylibrary")      // Adds a remote binary dependency only for local tests.     testImplementation 'junit:junit:4.12'      // Adds a remote binary dependency only for the instrumented test APK.     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }

ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่าการขึ้นต่อกันได้ที่เพิ่มการขึ้นต่อกันของบิลด์

ใช้การจัดการการขึ้นต่อกันที่รับรู้ตัวแปร

ปลั๊กอิน Android Gradle 3.0.0 ขึ้นไปมีกลไกการพึ่งพาใหม่ที่จับคู่ตัวแปรโดยอัตโนมัติ เมื่อใช้ไลบรารี ซึ่งหมายความว่าdebug รูปแบบ ของแอปจะใช้debug รูปแบบของไลบรารีโดยอัตโนมัติ และอื่นๆ นอกจากนี้ยังใช้ได้เมื่อใช้ Flavor ด้วย กล่าวคือ ตัวแปร freeDebug ของแอปจะใช้ตัวแปร freeDebug ของไลบรารี

คุณต้องระบุตัวสำรองที่ตรงกันตามที่อธิบายไว้ในส่วนต่อไปนี้ เพื่อให้ปลั๊กอินจับคู่ตัวแปรได้อย่างถูกต้องในกรณีที่จับคู่โดยตรงไม่ได้

ตัวอย่างเช่น สมมติว่าแอปของคุณกำหนดค่าประเภทบิลด์ที่ชื่อ "staging" แต่การอ้างอิงไลบรารีอย่างใดอย่างหนึ่ง ไม่ได้กำหนดค่า เมื่อปลั๊กอินพยายามสร้างแอปเวอร์ชัน "สเตจ" ปลั๊กอินจะไม่ทราบว่าจะใช้ไลบรารีเวอร์ชันใด และคุณจะเห็นข้อความแสดงข้อผิดพลาดที่คล้ายกับ ข้อความต่อไปนี้

 Error:Failed to resolve: Could not resolve project :mylibrary. Required by:     project :app 

แก้ไขข้อผิดพลาดในการสร้างที่เกี่ยวข้องกับการจับคู่ตัวแปร

ปลั๊กอินมีองค์ประกอบ DSL ที่ช่วยให้คุณควบคุมวิธีที่ Gradle แก้ไขสถานการณ์ที่แอปและ Dependency ไม่สามารถจับคู่ตัวแปรโดยตรงได้

ต่อไปนี้คือรายการปัญหาที่เกี่ยวข้องกับการจับคู่การอ้างอิงที่รับรู้ถึงตัวแปรและวิธี แก้ปัญหาโดยใช้พร็อพเพอร์ตี้ DSL

  • แอปของคุณมีประเภทบิลด์ที่การอ้างอิงไลบรารีไม่มี

    เช่น แอปของคุณมีประเภทบิลด์ "staging" แต่การขึ้นต่อกันมีเฉพาะประเภทบิลด์ "debug" และ "release"

    โปรดทราบว่าไม่มีปัญหาเมื่อการอ้างอิงไลบรารีมีประเภทบิลด์ ที่แอปของคุณไม่มี เนื่องจากปลั๊กอินไม่เคย ขอประเภทบิลด์นั้นจาก Dependency

    ใช้ matchingFallbacks เพื่อระบุการจับคู่สำรองสำหรับประเภทบิลด์ที่กำหนด ดังที่แสดงที่นี่

    Kotlin

    // In the app's build.gradle.kts file. android {     buildTypes {         getByName("debug") {}         getByName("release") {}         create("staging") {             // Specifies a sorted list of fallback build types that the             // plugin can try to use when a dependency does not include a             // "staging" build type. You may specify as many fallbacks as you             // like, and the plugin selects the first build type that's             // available in the dependency.             matchingFallbacks += listOf("debug", "qa", "release")         }     } }

    Groovy

    // In the app's build.gradle file. android {     buildTypes {         debug {}         release {}         staging {             // Specifies a sorted list of fallback build types that the             // plugin can try to use when a dependency does not include a             // "staging" build type. You may specify as many fallbacks as you             // like, and the plugin selects the first build type that's             // available in the dependency.             matchingFallbacks = ['debug', 'qa', 'release']         }     } }
  • สำหรับมิติข้อมูลรสชาติที่กำหนดซึ่งมีอยู่ในทั้งแอปและทรัพยากร Dependency ของไลบรารี แอปจะมีรสชาติที่ไลบรารีไม่มี

    เช่น ทั้งแอปและทรัพยากร Dependency ของไลบรารีมีมิติข้อมูลรสชาติ "ระดับ" อย่างไรก็ตาม มิติข้อมูล "ระดับ" ในแอปมีทั้งแบบ "ฟรี" และ "แบบชำระเงิน" แต่ การอ้างอิงมีเฉพาะแบบ "เดโม" และ "แบบชำระเงิน" สำหรับมิติข้อมูลเดียวกัน

    โปรดทราบว่าสำหรับมิติข้อมูลรสชาติที่กำหนดซึ่งมีอยู่ในทั้งแอปและทรัพยากร Dependency ของไลบรารี จะไม่มีปัญหาเมื่อไลบรารีมีรสชาติผลิตภัณฑ์ที่แอปของคุณไม่มี เนื่องจากปลั๊กอินไม่เคยขอรสชาตินั้นจาก Dependency

    ใช้ matchingFallbacks เพื่อระบุการจับคู่ทางเลือกสำหรับรสชาติผลิตภัณฑ์ "ฟรี" ของแอป ดังที่แสดงที่นี่

    Kotlin

    // In the app's build.gradle.kts file. android {     defaultConfig{     // Don't configure matchingFallbacks in the defaultConfig block.     // Instead, specify fallbacks for a given product flavor in the     // productFlavors block, as shown below.   }     flavorDimensions += "tier"     productFlavors {         create("paid") {             dimension = "tier"             // Because the dependency already includes a "paid" flavor in its             // "tier" dimension, you don't need to provide a list of fallbacks             // for the "paid" flavor.         }         create("free") {             dimension = "tier"             // Specifies a sorted list of fallback flavors that the plugin             // can try to use when a dependency's matching dimension does             // not include a "free" flavor. Specify as many             // fallbacks as you like; the plugin selects the first flavor             // that's available in the dependency's "tier" dimension.             matchingFallbacks += listOf("demo", "trial")         }     } }

    Groovy

    // In the app's build.gradle file. android {     defaultConfig{     // Don't configure matchingFallbacks in the defaultConfig block.     // Instead, specify fallbacks for a given product flavor in the     // productFlavors block, as shown below.   }     flavorDimensions 'tier'     productFlavors {         paid {             dimension 'tier'             // Because the dependency already includes a "paid" flavor in its             // "tier" dimension, you don't need to provide a list of fallbacks             // for the "paid" flavor.         }         free {             dimension 'tier'             // Specifies a sorted list of fallback flavors that the plugin             // can try to use when a dependency's matching dimension does             // not include a "free" flavor. Specify as many             // fallbacks as you like; the plugin selects the first flavor             // that's available in the dependency's "tier" dimension.             matchingFallbacks = ['demo', 'trial']         }     } }
  • ทรัพยากร Dependency ของไลบรารีมีมิติข้อมูลรสชาติที่แอปของคุณไม่มี

    ตัวอย่างเช่น ทรัพยากร Dependency ของไลบรารีมี Flavor สำหรับมิติข้อมูล "minApi" แต่แอปของคุณ มี Flavor สำหรับมิติข้อมูล "tier" เท่านั้น เมื่อคุณต้องการสร้างแอปเวอร์ชัน "freeDebug" ปลั๊กอินจะไม่ทราบว่าจะใช้เวอร์ชัน "minApi23Debug" หรือ "minApi18Debug" ของการขึ้นต่อกัน

    โปรดทราบว่าไม่มีปัญหาเมื่อแอปของคุณมีมิติข้อมูลรสชาติที่การอ้างอิงไลบรารีไม่มี เนื่องจากปลั๊กอินจะจับคู่ Flavor ของเฉพาะมิติข้อมูลที่ อยู่ใน Dependency เช่น หากการขึ้นต่อกันไม่มีมิติข้อมูลสำหรับ ABI แอปเวอร์ชัน "freeX86Debug" จะใช้เวอร์ชัน "freeDebug" ของ การขึ้นต่อกัน

    ใช้ missingDimensionStrategy ในบล็อก defaultConfig เพื่อระบุ รสชาติเริ่มต้นสำหรับปลั๊กอินที่จะเลือกจากมิติข้อมูลที่ขาดหายไปแต่ละรายการ ดังที่แสดงใน ตัวอย่างต่อไปนี้ นอกจากนี้ คุณยังลบล้างการเลือกในproductFlavors ได้ด้วย เพื่อให้แต่ละเวอร์ชันระบุกลยุทธ์การจับคู่ที่แตกต่างกันสำหรับมิติข้อมูลที่ขาดหายไปได้

    Kotlin

    // In the app's build.gradle.kts file. android {     defaultConfig{     // Specifies a sorted list of flavors that the plugin can try to use from     // a given dimension. This tells the plugin to select the "minApi18" flavor     // when encountering a dependency that includes a "minApi" dimension.     // You can include additional flavor names to provide a     // sorted list of fallbacks for the dimension.     missingDimensionStrategy("minApi", "minApi18", "minApi23")     // Specify a missingDimensionStrategy property for each     // dimension that exists in a local dependency but not in your app.     missingDimensionStrategy("abi", "x86", "arm64")     }     flavorDimensions += "tier"     productFlavors {         create("free") {             dimension = "tier"             // You can override the default selection at the product flavor             // level by configuring another missingDimensionStrategy property             // for the "minApi" dimension.             missingDimensionStrategy("minApi", "minApi23", "minApi18")         }         create("paid") {}     } }

    Groovy

    // In the app's build.gradle file. android {     defaultConfig{     // Specifies a sorted list of flavors that the plugin can try to use from     // a given dimension. This tells the plugin to select the "minApi18" flavor     // when encountering a dependency that includes a "minApi" dimension.     // You can include additional flavor names to provide a     // sorted list of fallbacks for the dimension.     missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'     // Specify a missingDimensionStrategy property for each     // dimension that exists in a local dependency but not in your app.     missingDimensionStrategy 'abi', 'x86', 'arm64'     }     flavorDimensions 'tier'     productFlavors {         free {             dimension 'tier'             // You can override the default selection at the product flavor             // level by configuring another missingDimensionStrategy property             // for the 'minApi' dimension.             missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'         }         paid {}     } }

ดูข้อมูลเพิ่มเติมได้ที่ matchingFallbacks และ missingDimensionStrategy ในข้อมูลอ้างอิง DSL ของปลั๊กอิน Android Gradle

กำหนดการตั้งค่าการลงนาม

Gradle จะไม่ลงนามใน APK หรือ AAB ของบิลด์รุ่นที่เผยแพร่ เว้นแต่คุณจะกำหนดค่าการลงนามสำหรับบิลด์นี้อย่างชัดเจน หากยังไม่มีคีย์การลงนาม ให้สร้างคีย์การอัปโหลดและที่เก็บคีย์ โดยใช้ Android Studio

หากต้องการกำหนดค่าการลงนามสำหรับประเภทบิลด์รุ่นด้วยตนเอง โดยใช้การกำหนดค่าบิลด์ Gradle ให้ทำดังนี้

  1. สร้างคีย์สโตร์ คีย์สโตร์คือไฟล์ไบนารี ที่มีชุดคีย์ส่วนตัว คุณต้องเก็บคีย์สโตร์ไว้ในที่ที่ปลอดภัย
  2. สร้างคีย์ส่วนตัว คีย์ส่วนตัวใช้เพื่อลงนามในแอป สำหรับการเผยแพร่ และจะไม่รวมไว้กับแอปหรือเปิดเผยต่อบุคคลที่สามที่ไม่ได้รับอนุญาต
  3. เพิ่มการกำหนดค่าการลงนามลงในไฟล์ build.gradle.kts ระดับโมดูล

    Kotlin

    ... android {     ...     defaultConfig {...}     signingConfigs {         create("release") {             storeFile = file("myreleasekey.keystore")             storePassword = "password"             keyAlias = "MyReleaseKey"             keyPassword = "password"         }     }     buildTypes {         getByName("release") {             ...             signingConfig = signingConfigs.getByName("release")         }     } }

    Groovy

    ... android {     ...     defaultConfig {...}     signingConfigs {         release {             storeFile file("myreleasekey.keystore")             storePassword "password"             keyAlias "MyReleaseKey"             keyPassword "password"         }     }     buildTypes {         release {             ...             signingConfig signingConfigs.release         }     } }

หมายเหตุ: การใส่รหัสผ่านสำหรับคีย์รุ่นและ keystore ไว้ในไฟล์บิลด์ไม่ใช่แนวทางปฏิบัติที่ดีด้านความปลอดภัย แต่ให้กำหนดค่าไฟล์บิลด์เพื่อรับรหัสผ่านเหล่านี้จากตัวแปรสภาพแวดล้อม หรือให้กระบวนการบิลด์แจ้งให้คุณป้อนรหัสผ่านเหล่านี้แทน

วิธีรับรหัสผ่านเหล่านี้จากตัวแปรสภาพแวดล้อม

Kotlin

storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")

Groovy

storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")

หรือจะโหลดที่เก็บคีย์จากไฟล์พร็อพเพอร์ตี้ในเครื่องก็ได้ เพื่อความปลอดภัย โปรดอย่า เพิ่มไฟล์นี้ลงในการควบคุมแหล่งที่มา แต่ให้ตั้งค่าในเครื่องสำหรับนักพัฒนาแอปแต่ละคนแทน ดูข้อมูลเพิ่มเติมได้ที่ นำข้อมูลการลงนามออกจากไฟล์บิลด์

หลังจากดำเนินการตามกระบวนการนี้เสร็จแล้ว คุณจะสามารถเผยแพร่และเผยแพร่แอปใน Google Play ได้

คำเตือน: โปรดเก็บคีย์สโตร์และคีย์ส่วนตัวไว้ในที่ที่ปลอดภัย และตรวจสอบว่าคุณได้สำรองข้อมูลดังกล่าวอย่างปลอดภัย หากใช้ Play App Signing และคีย์การอัปโหลดสูญหาย คุณสามารถขอรีเซ็ตโดยใช้ Play Console ได้ หากคุณเผยแพร่แอปโดยไม่ใช้ Play App Signing (สำหรับแอปที่สร้างขึ้นก่อนเดือนสิงหาคม 2021) และทำคีย์ App Signing หาย คุณจะเผยแพร่อัปเดตใดๆ ในแอปไม่ได้ เนื่องจากคุณต้องลงนามในแอปทุกเวอร์ชันด้วยคีย์เดียวกันเสมอ

การลงนามในแอป Wear OS

เมื่อเผยแพร่แอป Wear OS ทั้ง APK ของนาฬิกาและ APK ของโทรศัพท์ (ไม่บังคับ) ต้องลงนามด้วยคีย์เดียวกัน ดูข้อมูลเพิ่มเติมเกี่ยวกับการรวมแพ็กเกจและการลงนามแอป Wear OS ได้ที่ รวมแพ็กเกจและจัดจำหน่ายแอป Wear