หน้านี้แสดงวิธีกำหนดค่าตัวแปรบิลด์เพื่อ สร้างแอปเวอร์ชันต่างๆ จากโปรเจ็กต์เดียว รวมถึงวิธี จัดการการกำหนดค่าการลงนามและการขึ้นต่อกันอย่างเหมาะสม
ตัวแปรบิลด์แต่ละรายการแสดงถึงแอปเวอร์ชันต่างๆ ที่คุณสร้างได้ เช่น คุณอาจต้องการสร้างแอปเวอร์ชันหนึ่ง ที่ให้บริการฟรีพร้อมเนื้อหาแบบจำกัด และอีกเวอร์ชันหนึ่งที่ต้องชำระเงิน ซึ่งมีเนื้อหามากกว่า นอกจากนี้ คุณยังสร้างแอปเวอร์ชันต่างๆ ที่กำหนดเป้าหมายเป็นอุปกรณ์ที่แตกต่างกันได้ โดยอิงตามระดับ 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]
หากต้องการดูเอาต์พุตนี้ ให้ทำตามขั้นตอนต่อไปนี้
- คลิก Gradle ในแถบหน้าต่างเครื่องมือ
ไปที่ MyApplication > Tasks > android แล้ว ดับเบิลคลิก sourceSets
หากต้องการดูโฟลเดอร์ Tasks คุณต้องอนุญาตให้ Gradle สร้างรายการงาน ระหว่างการซิงค์ โดยทำตามขั้นตอนต่อไปนี้
- คลิกไฟล์ > การตั้งค่า > ทดลอง (Android Studio > การตั้งค่า > ทดลอง ใน macOS)
- ยกเลิกการเลือกไม่ต้อง สร้างรายการงาน Gradle ระหว่างการซิงค์ Gradle
- หลังจาก Gradle ดำเนินการในงานแล้ว หน้าต่างเรียกใช้จะเปิดขึ้นเพื่อแสดงเอาต์พุต
หมายเหตุ: เอาต์พุตของงานยังแสดงวิธีจัดระเบียบชุดแหล่งที่มา
สำหรับไฟล์ที่คุณต้องการใช้เพื่อเรียกใช้การทดสอบสำหรับแอป เช่น
test/ และ androidTest/
ชุดแหล่งที่มาสำหรับการทดสอบ
เมื่อสร้างตัวแปรบิลด์ใหม่ Android Studio จะไม่สร้างไดเรกทอรีชุดแหล่งที่มาให้ แต่จะมีตัวเลือก 2-3 อย่างที่จะช่วยคุณได้ เช่น หากต้องการสร้างเฉพาะไดเรกทอรี java/ สำหรับประเภทบิลด์ "debug"
ให้ทำดังนี้
- เปิดแผงโปรเจ็กต์ แล้วเลือกมุมมองโปรเจ็กต์จากเมนูที่ด้านบนของแผง
- ไปที่
MyProject/app/src/ - คลิกขวาที่ไดเรกทอรี
srcแล้วเลือก New > Directory - จากเมนูในส่วนชุดแหล่งที่มาของ Gradle ให้เลือก full/java
- กด Enter
Android Studio จะสร้างไดเรกทอรีชุดแหล่งที่มาสำหรับประเภทบิลด์การแก้ไขข้อบกพร่อง และ
จากนั้นจะสร้างไดเรกทอรี java/ ภายใน หรือ Android Studio จะสร้างไดเรกทอรีให้คุณเมื่อเพิ่มไฟล์ใหม่ลงใน
โปรเจ็กต์สำหรับตัวแปรบิลด์ที่เฉพาะเจาะจง
เช่น หากต้องการสร้างไฟล์ XML ของค่าสำหรับประเภทบิลด์ "debug" ให้ทำดังนี้
- ในแผงโปรเจ็กต์ ให้คลิกขวาที่ไดเรกทอรี
srcแล้วเลือกใหม่ > XML > ไฟล์ XML ของค่า - ป้อนชื่อไฟล์ XML หรือใช้ชื่อเริ่มต้น
- จากเมนูข้างชุดแหล่งข้อมูลเป้าหมาย ให้เลือก debug
- คลิกเสร็จสิ้น
เนื่องจากมีการระบุประเภทบิลด์ "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 จะดูไดเรกทอรีเหล่านี้และกำหนดลำดับความสำคัญต่อไปนี้
-
src/demoDebug/(ชุดแหล่งที่มาของตัวแปรบิลด์) -
src/debug/(ชุดแหล่งที่มาของประเภทบิลด์) -
src/demo/(ชุดแหล่งที่มาของเวอร์ชันผลิตภัณฑ์) -
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 ให้ทำดังนี้
- สร้างคีย์สโตร์ คีย์สโตร์คือไฟล์ไบนารี ที่มีชุดคีย์ส่วนตัว คุณต้องเก็บคีย์สโตร์ไว้ในที่ที่ปลอดภัย
- สร้างคีย์ส่วนตัว คีย์ส่วนตัวใช้เพื่อลงนามในแอป สำหรับการเผยแพร่ และจะไม่รวมไว้กับแอปหรือเปิดเผยต่อบุคคลที่สามที่ไม่ได้รับอนุญาต
-
เพิ่มการกำหนดค่าการลงนามลงในไฟล์
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