Halaman ini menunjukkan cara mengonfigurasi varian build untuk membuat versi aplikasi yang berbeda dari sebuah project dan cara mengelola konfigurasi penandatanganan dan dependensi dengan benar.
Setiap varian build menyatakan versi aplikasi berbeda yang dapat Anda build. Misalnya, Anda ingin mem-build satu versi aplikasi gratis dengan materi terbatas, dan versi lainnya yaitu versi berbayar yang berisi lebih banyak materi. Anda juga dapat mem-build versi lain aplikasi yang menargetkan perangkat berbeda, berdasarkan API level atau variasi perangkat lainnya.
Varian build adalah hasil dari Gradle yang menggunakan seperangkat aturan tertentu untuk menggabungkan setelan, kode, dan resource yang dikonfigurasi dalam jenis build dan ragam produk. Meskipun tidak harus mengonfigurasi varian build secara langsung, Anda perlu mengonfigurasi jenis build dan ragam produk yang membentuknya.
Misalnya, ragam produk "demo" mungkin menetapkan fitur
dan persyaratan perangkat tertentu, seperti kode sumber khusus, resource, dan API level
minimum, sedangkan jenis build "debug" menerapkan setelan build dan
paket yang berbeda, seperti opsi debug dan kunci penandatanganan. Varian
build yang menggabungkan keduanya adalah versi "demoDebug" untuk aplikasi Anda, dan varian tersebut mencakup
kombinasi konfigurasi dan resource yang disertakan dalam ragam produk
"demo", jenis build "debug", dan main/
set sumber.
Mengonfigurasi jenis build
Anda dapat membuat dan mengonfigurasi jenis build di dalam blok android
file build.gradle.kts
level modul. Saat Anda membuat
modul baru, Android Studio akan otomatis membuat jenis build rilis dan
debug. Meskipun jenis build debug tidak muncul dalam file konfigurasi
build, Android Studio akan mengonfigurasinya dengan debuggable
true
. Ini memungkinkan Anda men-debug aplikasi di perangkat Android yang aman dan
mengonfigurasi penandatanganan aplikasi dengan keystore debug generik.
Anda dapat menambahkan jenis build debug ke konfigurasi jika ingin menambahkan
atau mengubah setelan tertentu. Contoh berikut menentukan
applicationIdSuffix
untuk jenis build debug dan mengonfigurasi
jenis build "staging" yang diinisialisasi menggunakan setelan dari jenis build debug:
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" } } }
Catatan: Jika Anda membuat perubahan pada file konfigurasi build, Android Studio akan mengharuskan Anda untuk menyinkronkan project dengan konfigurasi baru. Untuk menyinkronkan project, klik Sync Now dalam baris notifikasi yang muncul saat Anda membuat perubahan atau klik Sync Project dari toolbar. Jika Android Studio menemukan error pada konfigurasi Anda, jendela Messages akan muncul untuk menjelaskan masalah tersebut.
Untuk mempelajari lebih lanjut semua properti yang dapat Anda konfigurasikan dengan jenis build,
baca referensi
BuildType
.
Mengonfigurasi ragam produk
Membuat ragam produk hampir sama dengan membuat jenis build. Tambahkan ragam produk ke
blok productFlavors
dalam konfigurasi build Anda dan sertakan setelan yang Anda inginkan.
Ragam produk mendukung properti yang sama seperti
defaultConfig
, karena defaultConfig
sebenarnya termasuk class
ProductFlavor
. Hal ini berarti Anda dapat menyediakan konfigurasi dasar
untuk semua ragam dalam blok defaultConfig
, dan
setiap ragam dapat mengubah bagian mana pun dari nilai default ini, misalnya applicationId
. Untuk
mempelajari ID aplikasi lebih lanjut, baca
Menyetel ID Aplikasi.
Catatan: Anda masih harus menentukan nama paket menggunakan
atribut package
dalam file manifes main/
. Anda juga harus menggunakan
nama paket tersebut dalam kode sumber untuk mereferensi ke class R
atau menetapkan
aktivitas relatif atau pendaftaran layanan. Ini memungkinkan Anda menggunakan
applicationId
sehingga memberi setiap ragam produk sebuah ID unik untuk
pemaketan dan distribusi, tanpa harus mengubah kode sumber.
Semua ragam harus dimiliki oleh dimensi ragam bernama, yang merupakan kelompok ragam produk. Anda harus menetapkan semua ragam ke dimensinya; jika tidak, Anda akan mengalami error build berikut.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
Jika modul yang diberikan hanya menentukan satu dimensi ragam, plugin Android Gradle akan otomatis menetapkan semua ragam modul ke dimensi tersebut.
Contoh kode berikut akan membuat dimensi ragam yang diberi nama "version" dan menambahkan
ragam produk "demo" dan "full". Ragam ini memberikan
applicationIdSuffix
dan
versionNameSuffix
-nya sendiri:
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" } } }
Catatan: Jika Anda memiliki aplikasi lama (dibuat sebelum
Agustus 2021) yang didistribusikan menggunakan APK di Google Play, untuk mendistribusikan aplikasi menggunakan dukungan
multi-APK di Google Play, tetapkan nilai applicationId
yang sama ke semua varian dan berikan setiap varian
versionCode
yang berbeda. Untuk mendistribusikan
varian lain dari aplikasi Anda sebagai aplikasi terpisah di Google Play, Anda perlu menetapkan
applicationId
yang berbeda ke setiap varian.
Setelah Anda membuat dan mengonfigurasi ragam produk, klik Sync Now di baris notifikasi. Setelah sinkronisasi selesai, Gradle
akan otomatis membuat varian build berdasarkan jenis build dan ragam
produk Anda, dan memberinya nama yang sesuai dengan
<product-flavor><Build-Type>
. Misalnya, jika Anda
membuat ragam produk “demo” dan “full”, dan mempertahankan jenis build default
“debug” dan
“release”, Gradle akan membuat varian build berikut:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
Untuk memilih varian build yang akan di-build dan dijalankan, buka Build > Select Build Variant dan pilih varian build dari menu. Untuk mulai menyesuaikan setiap varian build dengan fitur dan resource-nya sendiri, Anda harus membuat dan mengelola set sumber, seperti dijelaskan di halaman ini.
Mengubah ID aplikasi untuk varian build
Ketika Anda mem-build APK atau AAB untuk aplikasi, alat build akan menandai aplikasi dengan
ID aplikasi yang ditentukan dalam blok defaultConfig
dari file
build.gradle.kts
, seperti ditunjukkan dalam contoh berikut. Namun, jika Anda ingin membuat versi lain
aplikasi agar muncul sebagai listingan terpisah di Google Play Store, seperti versi "free" dan "pro",
Anda harus membuat
varian build terpisah yang masing-masing memiliki
ID aplikasi yang berbeda.
Dalam hal ini, tentukan setiap varian build sebagai
ragam produk terpisah. Untuk setiap ragam
dalam blok productFlavors
, Anda dapat menentukan ulang properti applicationId
,
atau menambahkan segmen ke ID aplikasi
default menggunakan applicationIdSuffix
, seperti yang ditampilkan di sini:
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" } } }
Dengan demikian, ID aplikasi untuk ragam produk "free" adalah "com.example.myapp.free".
Anda juga dapat menggunakan applicationIdSuffix
untuk menambahkan segmen berdasarkan
jenis build, seperti yang ditampilkan di sini:
Kotlin
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
Groovy
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
Karena Gradle menerapkan konfigurasi jenis build setelah ragam produk, ID aplikasi untuk varian build "free debug" sekarang menjadi "com.example.myapp.free.debug". Ini berguna jika Anda ingin memiliki build debug dan rilis di perangkat yang sama, karena dua aplikasi tidak dapat memiliki ID aplikasi yang sama.
Jika Anda memiliki aplikasi lama (dibuat sebelum Agustus 2021) yang didistribusikan menggunakan APK di Google Play, dan ingin menggunakan listingan aplikasi yang sama untuk mendistribusikan beberapa APK yang masing-masing menargetkan konfigurasi perangkat yang berbeda, seperti API level, maka Anda harus menggunakan ID aplikasi yang sama untuk setiap varian build, tetapi memberikanversionCode
yang berbeda untuk setiap APK. Untuk mengetahui informasi selengkapnya, baca Dukungan multi-APK. Publikasi
yang menggunakan AAB tidak akan terpengaruh karena menggunakan satu artefak yang menggunakan satu
kode versi dan ID aplikasi secara default.
Tips: Jika perlu mereferensikan ID aplikasi dalam
file manifes, Anda dapat menggunakan placeholder ${applicationId}
dalam
atribut manifes apa pun. Pada proses build, Gradle akan mengganti tag ini dengan ID aplikasi
yang sebenarnya. Untuk mengetahui informasi selengkapnya, lihat Menginjeksi variabel
build ke dalam manifes.
Menggabungkan beberapa ragam produk dengan dimensi ragam
Dalam beberapa situasi, Anda mungkin ingin menggabungkan konfigurasi dari beberapa ragam produk. Misalnya, Anda mungkin ingin membuat konfigurasi yang berbeda untuk ragam produk "full" dan "demo" berdasarkan API level. Untuk melakukannya, plugin Android Gradle memungkinkan Anda membuat beberapa grup ragam produk sebagai dimensi ragam.
Saat mem-build aplikasi, Gradle akan menggabungkan konfigurasi ragam produk dari setiap dimensi ragam yang Anda tentukan, bersama konfigurasi jenis build, untuk membuat varian build akhir. Gradle tidak menggabungkan ragam produk yang dimiliki dimensi ragam yang sama.
Contoh kode berikut menggunakan properti
flavorDimensions
untuk membuat dimensi
ragam "mode" guna mengelompokkan ragam produk "full" dan "demo", serta dimensi
ragam "api" guna mengelompokkan konfigurasi ragam produk berdasarkan API level:
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" ... } } } ...
Jumlah varian build yang dibuat Gradle sama dengan produk dari jumlah ragam di setiap dimensi ragam dan jumlah jenis build yang Anda konfigurasikan. Jika Gradle memberi nama setiap varian build atau artefak terkait, ragam produk yang dimiliki dimensi ragam berprioritas lebih tinggi akan muncul terlebih dahulu, diikuti ragam dari dimensi berprioritas lebih rendah, diikuti dengan jenis build.
Dengan menggunakan konfigurasi build sebelumnya sebagai contoh, Gradle akan membuat total 12 varian build dengan skema penamaan berikut:
- Varian build:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- APK terkait:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- Misalnya,
- Varian build:
minApi24DemoDebug
- APK terkait:
app-minApi24-demo-debug.apk
Selain direktori set sumber yang dapat Anda buat untuk setiap ragam produk
individu dan varian build, Anda juga dapat membuat direktori set sumber
untuk setiap kombinasi ragam produk. Misalnya, Anda dapat membuat dan menambahkan sumber Java ke direktori src/demoMinApi24/java/
, dan Gradle hanya menggunakan sumber itu saat membuat varian yang menggabungkan kedua ragam produk tersebut.
Set sumber yang Anda buat untuk kombinasi ragam produk memiliki prioritas lebih tinggi daripada set sumber yang termasuk dalam setiap ragam produk individu. Untuk mempelajari lebih lanjut set sumber dan cara Gradle menggabungkan resource, baca bagian cara membuat set sumber.
Memfilter varian
Gradle membuat varian build untuk setiap kombinasi yang memungkinkan dari ragam produk dan jenis build yang Anda konfigurasikan. Namun, mungkin ada varian
build tertentu yang tidak Anda perlukan atau yang tidak masuk akal dalam
konteks project Anda. Untuk menghapus konfigurasi varian build tertentu,
buat filter varian di file build.gradle.kts
level modul.
Dengan menggunakan konfigurasi build dari bagian sebelumnya sebagai contoh,
anggaplah Anda hanya ingin mendukung API level 23 dan yang lebih baru untuk aplikasi
versi demo. Anda dapat menggunakan blok
variantFilter
untuk memfilter semua konfigurasi
varian build yang menggabungkan ragam produk “minApi21” dan “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) } } } ...
Setelah menambahkan filter varian ke konfigurasi build dan mengklik Sync Now di baris notifikasi, Gradle akan mengabaikan varian build yang memenuhi kondisi yang Anda tentukan. Varian build tidak lagi muncul dalam menu saat Anda mengklik Build > Select Build Variant dari panel menu atau Build Variants di kolom jendela alat.
Membuat set sumber
Secara default, Android Studio akan membuat
set sumber main/
dan direktori untuk
segala sesuatu yang ingin Anda bagikan di antara semua varian build Anda. Namun, Anda
dapat membuat set sumber baru untuk mengontrol secara persis file yang dikompilasi oleh Gradle serta
paket untuk jenis build, ragam produk (dan kombinasi
ragam produk (saat menggunakan dimensi
ragam), dan varian build tertentu.
Misalnya, Anda dapat menetapkan fungsi dasar
dalam set sumber main/
dan menggunakan set sumber
ragam produk untuk mengubah branding aplikasi Anda bagi klien berbeda, atau
menyertakan izin khusus dan fungsi logging hanya untuk varian build
yang menggunakan jenis build debug.
Gradle memperkirakan file dan direktori set sumber diatur dengan cara
tertentu, mirip dengan set sumber main/
. Misalnya, Gradle
memperkirakan file class Kotlin atau Java yang khusus untuk jenis build "debug"
ditempatkan dalam direktori src/debug/kotlin/
atau src/debug/java/
.
Plugin Android Gradle menyediakan tugas Gradle bermanfaat yang akan menunjukkan cara mengatur file Anda untuk setiap jenis build, ragam produk, dan varian build. Misalnya, contoh berikut dari output tugas menjelaskan tempat Gradle diperkirakan akan menemukan file tertentu untuk jenis build "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]
Untuk melihat output ini, ikuti langkah berikut:
- Klik Gradle di kolom jendela alat.
Buka MyApplication > Tasks > android lalu klik dua kali sourceSets.
Untuk melihat folder Tasks, Anda harus mengizinkan Gradle mem-build daftar tugas selama sinkronisasi. Untuk melakukannya, ikuti langkah-langkah berikut:
- Klik File > Settings > Experimental (Android Studio > Settings > Experimental di macOS).
- Batalkan pilihan Jangan build daftar tugas Gradle selama sinkronisasi Gradle.
- Setelah Gradle mengeksekusi tugas, jendela Run akan terbuka untuk menampilkan output-nya.
Catatan: Output tugas juga akan menunjukkan cara mengatur set sumber
untuk file yang ingin Anda gunakan dalam menjalankan pengujian bagi aplikasi Anda, seperti
set sumber pengujian
test/
dan androidTest/
.
Jika Anda membuat varian build baru, Android Studio tidak akan membuat direktori set
sumber, melainkan memberikan beberapa opsi untuk membantu Anda. Misalnya, untuk hanya membuat direktori java/
untuk jenis build "debug":
- Buka panel Project, lalu pilih tampilan Project dari menu di bagian atas panel.
- Buka
MyProject/app/src/
. - Klik kanan direktori
src
, lalu pilih New > Directory. - Dari menu di bagian Gradle Source Sets, pilih full/java.
- Tekan Enter.
Android Studio membuat direktori set sumber untuk jenis build debug, kemudian
membuat direktori java/
di dalamnya. Atau,
Android Studio dapat membuat direktori untuk Anda saat Anda menambahkan file baru ke
project Anda untuk varian build tertentu.
Misalnya, untuk membuat file XML nilai untuk jenis build "debug" Anda:
- Di panel Project, klik kanan direktori
src
dan pilih New > XML > Values XML File. - Masukkan nama untuk file XML atau tetap gunakan nama default.
- Dari menu di samping Target Source Set, pilih debug.
- Klik Finish.
Karena jenis build "debug" ditetapkan sebagai set sumber target, Android Studio akan otomatis membuat direktori yang diperlukan ketika membuat file XML. Struktur direktori yang dihasilkan terlihat seperti gambar 1.
Set sumber aktif memiliki indikator hijau di ikonnya untuk menunjukkan bahwa set sumber itu aktif. Set
sumber debug
diberi akhiran [main]
untuk menunjukkan bahwa set sumber tersebut akan digabungkan
ke set sumber main
.
Dengan menggunakan prosedur yang sama, Anda juga dapat membuat direktori set sumber untuk ragam produk seperti src/demo/
, dan varian build seperti src/demoDebug/
. Anda juga dapat membuat set sumber pengujian
yang menargetkan varian build tertentu, seperti
src/androidTestDemoDebug/
. Untuk mempelajari lebih lanjut, baca
set sumber pengujian.
Mengubah konfigurasi set sumber default
Jika Anda memiliki sumber yang tidak diatur ke struktur file set sumber default
yang diperkirakan Gradle, seperti dijelaskan dalam bagian sebelumnya tentang
membuat set sumber, Anda dapat menggunakan blok
sourceSets
untuk mengubah lokasi pencarian Gradle guna mengumpulkan
file untuk setiap komponen set sumber.
Blok sourceSets
harus berada
di blok android
. Anda tidak perlu memindahkan lokasi
file sumber. Anda hanya perlu memberi Gradle jalur ke file tersebut, tergantung file
build.gradle.kts
tingkat modulnya, tempat Gradle dapat
menemukan file untuk setiap komponen set sumber. Untuk mempelajari komponen mana yang dapat Anda
konfigurasi, dan apakah Anda dapat memetakannya ke beberapa file atau direktori,
lihat Referensi API plugin Android Gradle.
Contoh kode berikut memetakan sumber dari direktori app/other/
ke komponen tertentu dari set sumber main
dan mengubah
direktori utama set sumber 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' ... } } } ...
Perhatikan bahwa direktori sumber hanya bisa dimiliki oleh satu set sumber. Misalnya, Anda tidak dapat berbagi
sumber pengujian yang sama dengan set sumber test
dan androidTest
. Hal ini
dikarenakan Android Studio membuat modul IntelliJ terpisah untuk setiap set sumber, dan tidak dapat mendukung
root konten duplikat di seluruh set sumber.
Mem-build dengan set sumber
Anda dapat menggunakan direktori set sumber untuk memuat kode dan resource yang ingin Anda paketkan hanya dengan konfigurasi tertentu. Misalnya, jika Anda membuat varian build “demoDebug” yang merupakan produk persilangan ragam produk “demo” dan jenis build “debug”, Gradle akan melihat direktori ini dan memberinya prioritas berikut:
-
src/demoDebug/
(set sumber varian build) -
src/debug/
(set sumber jenis build) -
src/demo/
(set sumber ragam produk) -
src/main/
(set sumber utama)
Set sumber yang dibuat untuk kombinasi ragam produk harus menyertakan semua dimensi ragam. Misalnya, set sumber varian build harus merupakan kombinasi dari jenis build dan semua dimensi ragam. Penggabungan kode dan resource yang melibatkan folder yang mencakup beberapa, tetapi tidak semua, dimensi ragam tidak didukung.
Jika Anda menggabungkan beberapa ragam
produk, prioritas antara ragam produk ditentukan oleh dimensi
ragam yang mencakupnya. Saat mencantumkan dimensi ragam dengan properti
android.flavorDimensions
, ragam produk yang
termasuk dalam dimensi ragam pertama yang Anda cantumkan akan memiliki prioritas lebih tinggi daripada
ragam produk yang termasuk dalam dimensi ragam kedua, dan seterusnya. Selain itu,
set sumber yang Anda buat untuk kombinasi ragam produk memiliki prioritas lebih tinggi
daripada set sumber yang termasuk dalam setiap ragam produk individu.
Urutan prioritas menentukan set sumber yang memiliki prioritas
lebih tinggi saat Gradle menggabungkan kode dan resource. Karena direktori set sumber demoDebug/
kemungkinan berisi file yang dikhususkan untuk varian build terkait, jika demoDebug/
memuat file yang juga ditentukan di debug/
, Gradle akan menggunakan file tersebut dalam set sumber demoDebug/
. Demikian pula, Gradle akan memberi file dalam set sumber jenis build dan ragam produk prioritas yang lebih tinggi daripada file yang sama yang berada di main/
.
Gradle mempertimbangkan urutan prioritas ini saat menerapkan aturan build berikut:
- Semua kode sumber dalam direktori
kotlin/
ataujava/
dikompilasi bersama untuk menghasilkan satu output.Catatan: Untuk varian build tertentu, Gradle akan menampilkan error build jika menemukan dua atau lebih direktori set sumber yang telah menentukan class Kotlin atau Java yang sama. Misalnya, jika mem-build aplikasi debug, Anda tidak dapat menetapkan
src/debug/Utility.kt
dansrc/main/Utility.kt
sekaligus, karena Gradle melihat kedua direktori ini selama proses build dan menampilkan error "class duplikat". Jika Anda menginginkan versiUtility.kt
yang berbeda untuk jenis build yang berbeda, setiap jenis build harus menentukan versi filenya sendiri dan tidak menyertakannya dalam set sumbermain/
. - Beberapa manifes digabungkan menjadi satu manifes. Prioritas diberikan dengan urutan yang sama seperti dalam daftar pada contoh sebelumnya. Artinya, setelan manifes untuk jenis build akan menggantikan setelan manifes untuk ragam produk, dan seterusnya. Untuk mempelajari lebih lanjut, baca penggabungan manifes.
- Demikian juga, file dalam direktori
values/
digabungkan bersama-sama. Jika dua file memiliki nama yang sama, misalnya dua filestrings.xml
, prioritas akan diberikan dengan urutan yang sama seperti dalam daftar di contoh sebelumnya. Artinya, nilai yang ditentukan dalam file di set sumber jenis build akan menggantikan nilai yang ditentukan dalam file yang sama di ragam produk, dan seterusnya. - Resource di direktori
res/
danasset/
dipaketkan bersama-sama. Jika beberapa resource dengan nama yang sama ditetapkan dalam dua atau lebih set sumber, prioritas akan diberikan dengan urutan yang sama seperti dalam daftar di contoh sebelumnya. - Gradle akan memberikan prioritas terendah ke resource dan manifes yang disertakan bersama dependensi modul library saat mem-build aplikasi.
Mendeklarasikan dependensi
Untuk mengonfigurasi dependensi untuk varian build atau
set sumber pengujian tertentu,
tambahkan awalan ke nama varian build atau set sumber pengujian sebelum
kata kunci Implementation
, seperti ditunjukkan dalam contoh berikut:
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' }
Untuk mengetahui informasi selengkapnya tentang cara mengonfigurasi dependensi, lihat Menambahkan dependensi build.
Menggunakan pengelolaan dependensi berdasarkan varian
Plugin Android Gradle 3.0.0 dan yang lebih tinggi menyertakan mekanisme dependensi baru yang otomatis
mencocokkan varian saat menggunakan library. Hal ini berarti varian debug
aplikasi akan
otomatis menggunakan varian debug
library, dan seterusnya. Plugin ini juga berfungsi saat menggunakan
ragam: varian freeDebug
aplikasi akan menggunakan varian
freeDebug
library.
Agar plugin mencocokkan varian secara akurat, Anda perlu menyediakan fallback pencocokan seperti yang dijelaskan di bagian berikut, untuk instance jika pencocokan langsung tidak memungkinkan.
Misalnya, aplikasi Anda mengonfigurasi jenis build yang disebut "staging", tetapi salah satu dependensi library-nya tidak. Saat mencoba mem-build versi "staging" aplikasi Anda, plugin tidak akan mengetahui versi library mana yang digunakan, dan Anda akan melihat pesan error yang mirip dengan berikut ini:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
Mengatasi error build yang berkaitan dengan pencocokan varian
Plugin menyertakan elemen DSL untuk membantu Anda mengontrol cara Gradle mengatasi situasi ketika pencocokan varian langsung antara aplikasi dan dependensi tidak mungkin dilakukan.
Berikut adalah daftar masalah yang terkait dengan pencocokan dependensi berdasarkan varian dan cara menyelesaikannya menggunakan properti DSL:Aplikasi Anda menyertakan jenis build yang tidak disertakan oleh dependensi library.
Misalnya, aplikasi Anda menyertakan jenis build "staging", tetapi dependensi hanya menyertakan jenis build "debug" dan "release".
Perhatikan bahwa tidak ada masalah jika dependensi library menyertakan jenis build yang tidak disertakan oleh aplikasi Anda. Hal ini dikarenakan plugin tidak pernah meminta jenis build tersebut dari dependensi.
Gunakan
matchingFallbacks
untuk menentukan pencocokan alternatif bagi jenis build tertentu, seperti ditunjukkan di bawah: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'] } } }
Untuk dimensi ragam tertentu yang ada dalam aplikasi dan dependensi library-nya, aplikasi Anda menyertakan ragam yang tidak disertakan oleh library.
Misalnya, aplikasi Anda dan dependensi library-nya menyertakan dimensi ragam "tier". Namun, dimensi "tier" dalam aplikasi menyertakan ragam "free" dan "paid", sementara dependensi hanya menyertakan ragam "demo" dan "paid" untuk dimensi yang sama.
Perlu diperhatikan bahwa untuk dimensi ragam tertentu yang ada dalam aplikasi dan dependensi library-nya, tidak akan ada masalah jika library menyertakan ragam produk yang tidak disertakan aplikasi Anda. Hal ini dikarenakan plugin tidak pernah meminta ragam tersebut dari dependensi.
Gunakan
matchingFallbacks
untuk menentukan pencocokan alternatif bagi ragam produk "free" aplikasi, seperti ditunjukkan di bawah: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'] } } }
Dependensi library menyertakan dimensi ragam yang tidak disertakan oleh aplikasi Anda.
Misalnya, dependensi library menyertakan ragam untuk dimensi "minApi", sementara aplikasi Anda hanya menyertakan ragam untuk dimensi "tier". Jadi, saat Anda ingin mem-build versi "freeDebug" untuk aplikasi, plugin tidak tahu apakah akan menggunakan versi dependensi "minApi23Debug" atau "minApi18Debug".
Perlu diperhatikan bahwa tidak akan ada masalah jika aplikasi Anda menyertakan dimensi ragam yang tidak disertakan oleh dependensi library. Hal ini dikarenakan plugin tersebut hanya mencocokkan ragam dari dimensi yang ada dalam dependensi. Misalnya, jika dependensi tidak menyertakan dimensi untuk ABI, versi "freeX86Debug" aplikasi Anda akan menggunakan versi "freeDebug" dependensi.
Gunakan
missingDimensionStrategy
dalam blokdefaultConfig
untuk menentukan ragam default yang harus dipilih plugin dari setiap dimensi yang tidak ditemukan, seperti ditunjukkan dalam contoh berikut. Anda juga dapat mengganti pilihan dalam blokproductFlavors
, sehingga setiap ragam dapat menentukan strategi pencocokan yang berbeda untuk dimensi yang tidak ditemukan.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 {} } }
Untuk mengetahui informasi selengkapnya, lihat matchingFallbacks
dan missingDimensionStrategy
dalam referensi DSL plugin Android Gradle.
Mengonfigurasi setelan penandatanganan
Gradle tidak menandatangani APK atau AAB build rilis kecuali jika Anda secara eksplisit menentukan konfigurasi penandatanganan untuk build ini. Jika Anda belum memiliki kunci penandatanganan, buat keystore dan kunci upload menggunakan Android Studio.
Untuk mengubah konfigurasi penandatanganan jenis build rilis Anda secara manual menggunakan konfigurasi build Gradle:
- Buat keystore. Keystore adalah file biner yang berisi seperangkat kunci pribadi. Anda harus menyimpan keystore di tempat yang aman dan terlindung.
- Buat kunci pribadi. Kunci pribadi digunakan untuk menandatangani aplikasi Anda untuk distribusi dan tidak pernah disertakan dalam aplikasi atau diungkapkan kepada pihak ketiga yang tidak sah.
-
Tambahkan konfigurasi penandatanganan ke file
build.gradle.kts
level modul: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 } } }
Catatan: Menyertakan sandi untuk kunci rilis dan keystore di dalam file build bukanlah praktik keamanan yang baik. Sebagai gantinya, konfigurasikan file build untuk memperoleh sandi ini dari variabel lingkungan atau setel agar proses build meminta sandi ini.
Untuk memperoleh sandi ini dari variabel lingkungan:
Kotlin
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
Groovy
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
Atau, Anda dapat memuat keystore dari file properti lokal. Untuk alasan keamanan, jangan tambahkan file ini ke kontrol sumber. Sebagai gantinya, siapkan secara lokal untuk setiap developer. Untuk mempelajari lebih lanjut, baca Menghapus informasi penandatanganan dari file build Anda.
Setelah menyelesaikan proses ini, Anda dapat mendistribusikan aplikasi dan memublikasikannya di Google Play.
Peringatan: Simpan keystore dan kunci pribadi Anda di tempat yang aman dan terlindungi, serta pastikan Anda memiliki cadangannya yang aman. Jika menggunakan Penandatanganan Aplikasi Play dan kehilangan kunci upload, Anda dapat meminta reset menggunakan Konsol Play. Jika memublikasikan aplikasi tanpa Penandatanganan Aplikasi Play (untuk aplikasi yang dibuat sebelum Agustus 2021) dan kunci penandatanganan aplikasi hilang, Anda tidak akan dapat memublikasikan update apa pun ke aplikasi, karena Anda harus selalu menandatangani semua versi aplikasi dengan kunci yang sama.
Menandatangani aplikasi Wear OS
Saat memublikasikan aplikasi Wear OS, APK smartwatch dan APK ponsel opsional harus ditandatangani dengan kunci yang sama. Untuk mengetahui informasi selengkapnya tentang memaketkan dan menandatangani aplikasi Wear OS, lihat Memaketkan dan mendistribusikan aplikasi Wear.