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

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

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

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

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

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

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

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

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"
        }
    }
}

ดึงดูด

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 ในการกำหนดค่าบิลด์และรวมการตั้งค่าที่คุณต้องการ รสชาติของผลิตภัณฑ์สนับสนุนคุณสมบัติเดียวกับ 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.

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

ตัวอย่างโค้ดต่อไปนี้สร้างมิติข้อมูลเวอร์ชันที่มีชื่อว่า "เวอร์ชัน" และเพิ่ม "สาธิต" และ "เต็ม" รสชาติของผลิตภัณฑ์ รสชาติเหล่านี้มีลักษณะเฉพาะตัว 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"
        }
    }
}

ดึงดูด

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> ตัวอย่างเช่น หากคุณ สร้าง "สาธิต" แล้ว และ "เต็ม" รสชาติของผลิตภัณฑ์ และคงค่าเริ่มต้นไว้ "แก้ไขข้อบกพร่อง" และ "เปิดตัว" ประเภทบิลด์ Gradle สร้างตัวแปรบิลด์ต่อไปนี้

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

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

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

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

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

Kotlin

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

ดึงดูด

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"
        }
    }
}

ดึงดูด

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

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

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

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

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

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

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

ตัวอย่างโค้ดต่อไปนี้ใช้ 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"
      ...
    }
  }
}
...

ดึงดูด

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 สร้างตัวแปรบิลด์สำหรับชุดค่าผสมของผลิตภัณฑ์ที่เป็นไปได้ทั้งหมด เวอร์ชันและประเภทบิลด์ที่คุณกำหนดค่า อย่างไรก็ตาม อาจมี สร้างตัวแปรที่คุณไม่ต้องการหรือไม่สมเหตุสมผล บริบทของโครงการ หากต้องการนำการกำหนดค่าตัวแปรบิลด์บางรายการออก สร้างตัวกรองตัวแปรในระดับโมดูล build.gradle.kts

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

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
        }
    }
}
...

ดึงดูด

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 คอมไพล์และ แพ็กเกจสำหรับประเภทงานสร้างที่เฉพาะเจาะจง รสชาติของผลิตภัณฑ์ การผสมผสาน รสชาติของผลิตภัณฑ์ (เมื่อใช้ flavor [รสชาติ] ขนาดต่างๆ) และตัวแปรของบิลด์

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

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

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

------------------------------------------------------------
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 > งาน > android และ ดับเบิลคลิก sourceSets

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

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

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

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

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

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

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

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

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

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

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

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

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

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

การบล็อก sourceSets ต้อง ในบล็อก android คุณไม่จำเป็นต้องย้าย ไฟล์ต้นฉบับ คุณต้องใส่เส้นทางที่สัมพันธ์กับ Gradle ไฟล์ build.gradle.kts ระดับโมดูล โดยที่ 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")
      ...
  }
}
...

ดึงดูด

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" ซึ่งเป็นตัวแปรข้ามผลิตภัณฑ์จาก "สาธิต" เวอร์ชันผลิตภัณฑ์และ "แก้ไขข้อบกพร่อง" ประเภทบิลด์ Gradle ดูที่ ไดเรกทอรีเหล่านี้และให้ลำดับความสำคัญดังต่อไปนี้

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

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

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

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

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

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

  • ไฟล์ Manifest จะรวมเข้าด้วยกันเป็นไฟล์ Manifest เดียว จัดลําดับความสําคัญแล้ว ในลำดับเดียวกับรายการในตัวอย่างก่อนหน้านี้ นั่นคือการตั้งค่าไฟล์ Manifest สำหรับบิลด์ ประเภทจะลบล้างการตั้งค่าไฟล์ Manifest สำหรับเวอร์ชันผลิตภัณฑ์ และอื่นๆ เพื่อเรียนรู้ อ่านเพิ่มเติมเกี่ยวกับการรวมไฟล์ Manifest
  • ระบบผสานไฟล์ในไดเรกทอรี values/ แล้ว ถ้าไฟล์ 2 ไฟล์มีชื่อเดียวกัน เช่น 2 ไฟล์ strings.xml ไฟล์จะได้รับลำดับความสำคัญตามลําดับเดียวกับ ในตัวอย่างก่อนหน้านี้ กล่าวคือ ค่าที่กำหนดไว้ในไฟล์ในชุดแหล่งที่มาของประเภทบิลด์ ลบล้างค่าที่กำหนดไว้ในไฟล์เดียวกันในรสชาติของผลิตภัณฑ์ เป็นต้น
  • ทรัพยากรในไดเรกทอรี 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.5.1")
}

ดึงดูด

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.5.1'
}

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

ใช้การจัดการทรัพยากร Dependency ที่คำนึงถึงตัวแปร

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

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

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

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

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

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

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

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

    เช่น แอปของคุณมี "การทดลองใช้" ประเภทบิลด์ แต่ทรัพยากร Dependency มีเฉพาะ "แก้ไขข้อบกพร่อง" และ "ปล่อย" ประเภทบิลด์

    โปรดทราบว่าจะไม่มีปัญหาเมื่อทรัพยากร Dependency ของไลบรารีมีบิลด์ ในแบบที่แอปของคุณไม่มี เนื่องจากปลั๊กอินจะไม่ คำขอที่สร้างประเภทจากทรัพยากร 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")
            }
        }
    }

    ดึงดูด

    // 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 ของแอปและไลบรารีของแอปมี "tier" มิติข้อมูลเวอร์ชัน อย่างไรก็ตาม "ระดับ" มิติข้อมูลในแอปมีคำว่า "ฟรี" และ "ชำระเงินแล้ว" มากกว่า 100 เปอร์เซ็นต์ ทรัพยากร 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")
            }
        }
    }
    

    ดึงดูด

    // 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 ของไลบรารีจะมีเวอร์ชันสำหรับ "minApi" แต่แอปของคุณ รวมรสชาติสำหรับ "ระดับ" เท่านั้น เมื่อคุณต้องการสร้าง "freeDebug" เวอร์ชันแอปของคุณ เนื่องจากปลั๊กอินจะไม่ทราบว่าควรใช้ "minApi23Debug" หรือไม่ หรือ "minApi18Debug" ของ Dependency ได้

    โปรดทราบว่าจะไม่พบปัญหาเมื่อแอปมีมิติข้อมูลรสชาติที่ไลบรารี ใช้ไม่ได้ เนื่องจากปลั๊กอินจะจับคู่รสชาติ ซึ่งมีขนาดที่ อยู่ในทรัพยากร Dependency โดยตรง ตัวอย่างเช่น หากทรัพยากร 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") {}
        }
    }
    

    ดึงดูด

    // 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 ของบิลด์ที่เผยแพร่ เว้นแต่คุณจะกำหนด การกำหนดค่าการรับรองสำหรับบิลด์นี้ หากคุณยังไม่มีคีย์ Signing สร้างคีย์การอัปโหลดและคีย์สโตร์ โดยใช้ Android Studio

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

  1. สร้างคีย์สโตร์ keystore คือไฟล์ไบนารี ที่มีชุดคีย์ส่วนตัว คุณต้องเก็บคีย์สโตร์ของคุณไว้ในที่ปลอดภัย และปลอดภัย
  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")
            }
        }
    }

    ดึงดูด

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

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

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

Kotlin

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

ดึงดูด

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