Perhatian: Sejak Agustus 2021, semua aplikasi baru harus dipublikasikan sebagai App Bundle. Jika Anda memublikasikan aplikasi ke Google Play, bangun dan upload Android App Bundle. Setelah Anda melakukannya, Google Play akan otomatis membuat dan menayangkan APK yang dioptimalkan untuk setiap konfigurasi perangkat pengguna, sehingga pengguna hanya mendownload kode dan resource yang diperlukan untuk menjalankan aplikasi Anda. Memublikasikan multi-APK akan berguna jika Anda memublikasikan ke app store yang tidak mendukung format AAB. Dalam hal ini, Anda harus membuat, menandatangani, dan mengelola sendiri setiap APK.
Meskipun akan lebih baik jika membuat satu APK untuk mendukung semua perangkat target Anda, jika memungkinkan, hal tersebut dapat menghasilkan APK yang sangat besar karena file yang mendukung berbagai kepadatan layar atau Antarmuka Biner Aplikasi (ABI). Salah satu cara untuk mengurangi ukuran APK adalah dengan membuat multi-APK yang berisi file untuk kepadatan layar atau ABI tertentu.
Gradle dapat membuat APK terpisah yang hanya berisi kode dan resource khusus untuk setiap kepadatan atau ABI. Halaman ini menjelaskan cara mengonfigurasi build Anda untuk membuat multi-APK. Jika Anda perlu membuat beberapa versi lain dari aplikasi Anda yang tidak didasarkan pada kepadatan layar atau ABI, gunakan varian build.
Mengonfigurasi build untuk multi-APK
Guna mengonfigurasi build Anda untuk multi-APK, tambahkan blok splits
ke file build.gradle
tingkat modul Anda. Dalam
blok splits
, sediakan
blok density
yang menentukan cara Gradle menghasilkan
APK untuk setiap kepadatan atau blok abi
yang menentukan cara Gradle
menghasilkan APK untuk setiap ABI. Anda dapat menyediakan kepadatan dan blok ABI, dan sistem build akan membuat APK untuk setiap kombinasi kepadatan dan ABI.
Mengonfigurasi multi-APK untuk kepadatan layar
Jika ingin membuat APK terpisah untuk kepadatan layar yang berbeda, tambahkan
blok density
di dalam
blok splits
Anda. Di blok density
, cantumkan
kepadatan layar yang diinginkan dan ukuran layar yang kompatibel. Hanya gunakan daftar
ukuran layar yang kompatibel jika Anda memerlukan elemen
<compatible-screens>
spesifik dalam setiap manifes APK.
Opsi Gradle DSL berikut digunakan untuk mengonfigurasi multi-APK untuk kepadatan layar:
-
enable
untuk Groovy,isEnable
untuk skrip Kotlin -
Jika Anda menetapkan elemen ini ke
true
, Gradle akan menghasilkan multi-APK berdasarkan kepadatan layar yang Anda tentukan. Nilai defaultnya adalahfalse
. -
exclude
-
Menentukan daftar yang dipisahkan koma untuk kepadatan yang APK terpisahnya tidak Anda inginkan dari Gradle. Gunakan
exclude
jika Anda ingin membuat APK untuk sebagian besar kepadatan, tetapi perlu mengecualikan beberapa kepadatan yang tidak didukung aplikasi Anda. -
reset()
-
Mengosongkan daftar default kepadatan layar. Gunakan opsi ini hanya jika dikombinasikan dengan elemen
include
untuk menentukan kepadatan yang ingin Anda tambahkan.Cuplikan berikut menetapkan daftar kepadatan untuk
ldpi
danxxhdpi
saja dengan memanggilreset()
untuk mengosongkan daftar, kemudian menggunakaninclude
:reset() // Clears the default list from all densities // to no densities. include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs // for.
-
include
-
Menentukan daftar yang dipisahkan koma untuk kepadatan yang APK-nya Anda inginkan untuk dihasilkan oleh Gradle. Hanya gunakan bersama
reset()
untuk menentukan daftar kepadatan yang pasti. -
compatibleScreens
-
Menentukan daftar dipisahkan koma untuk ukuran layar yang kompatibel. Tindakan ini akan memasukkan node
<compatible-screens>
yang cocok dalam manifes untuk setiap APK.Setelan ini memberikan cara yang mudah untuk mengelola kepadatan layar dan ukuran layar di bagian
build.gradle
yang sama. Namun, penggunaan<compatible-screens>
dapat membatasi jenis perangkat yang dapat digunakan aplikasi Anda. Untuk cara alternatif mendukung berbagai ukuran layar, lihat ringkasan kompatibilitas layar.
Karena setiap APK yang didasarkan pada kepadatan layar menyertakan tag
<compatible-screens>
dengan pembatasan khusus
terkait jenis layar yang didukung APK—meskipun Anda memublikasikan beberapa
APK—beberapa perangkat baru tidak cocok dengan beberapa filter APK Anda. Dengan demikian,
Gradle selalu membuat APK universal tambahan yang berisi aset
untuk semua kepadatan layar dan tidak menyertakan
tag <compatible-screens>
. Publikasikan
APK universal ini bersama APK untuk setiap kepadatan guna menyediakan penggantian bagi
perangkat yang tidak cocok dengan APK yang menyertakan
tag <compatible-screens>
.
Contoh berikut menghasilkan APK terpisah untuk setiap
kepadatan
layar, kecuali ldpi
, xxhdpi
, dan
xxxhdpi
. Hal ini dilakukan dengan menggunakan exclude
untuk menghapus
ketiga kepadatan tersebut dari daftar default semua kepadatan.
Groovy
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. enable true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude "ldpi", "xxhdpi", "xxxhdpi" // Specifies a list of compatible screen size settings for the manifest. compatibleScreens 'small', 'normal', 'large', 'xlarge' } } }
Kotlin
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. isEnable = true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude("ldpi", "xxhdpi", "xxxhdpi") // Specifies a list of compatible screen size settings for the manifest. compatibleScreens("small", "normal", "large", "xlarge") } } }
Untuk detail selengkapnya tentang menyesuaikan berbagai varian build aplikasi ke jenis layar dan perangkat tertentu, lihat Mendeklarasikan dukungan layar terbatas.
Mengonfigurasi multi-APK untuk ABI
Guna membuat APK terpisah untuk ABI berbeda, tambahkan blok abi
di dalam blok splits
Anda. Dalam blok abi
Anda, cantumkan ABI yang diinginkan.
Opsi Gradle DSL berikut digunakan untuk mengonfigurasi multi-APK per ABI:
-
enable
untuk Groovy, atauisEnable
untuk skrip Kotlin - Jika Anda menetapkan elemen ini ke
true
, Gradle akan menghasilkan multi-APK berdasarkan ABI yang Anda tentukan. Nilai defaultnya adalahfalse
. -
exclude
-
Menentukan daftar yang dipisahkan koma untuk ABI yang APK terpisahnya tidak Anda inginkan dari Gradle. Gunakan
exclude
jika Anda ingin membuat APK untuk sebagian besar ABI, tetapi perlu mengecualikan beberapa ABI yang tidak didukung aplikasi Anda. -
reset()
-
Menghapus daftar default ABI. Hanya gunakan opsi ini jika dikombinasikan dengan elemen
include
untuk menentukan ABI yang ingin Anda tambahkan.Cuplikan berikut menetapkan daftar ABI untuk
x86
danx86_64
saja dengan memanggilreset()
untuk mengosongkan daftar, kemudian menggunakaninclude
:reset() // Clears the default list from all ABIs to no ABIs. include "x86", "x86_64" // Specifies the two ABIs we want to generate APKs for.
-
include
-
Menentukan daftar yang dipisahkan koma untuk ABI yang APK-nya ingin dihasilkan oleh Gradle. Hanya gunakan opsi ini jika dikombinasikan dengan
reset()
untuk menentukan daftar pasti ABI. -
universalApk
untuk Groovy, atauisUniversalApk
untuk skrip Kotlin -
Jika
true
, Gradle akan menghasilkan APK universal selain APK untuk setiap ABI. APK universal berisi kode dan resource untuk semua ABI dalam satu APK. Nilai defaultnya adalahfalse
.Perhatikan bahwa opsi ini hanya tersedia dalam blok
splits.abi
. Saat membuat multi-APK berdasarkan kepadatan layar, Gradle selalu menghasilkan APK universal yang berisi kode dan resource untuk semua kepadatan layar.
Contoh berikut akan menghasilkan APK terpisah untuk setiap ABI: x86
dan x86_64
. Hal ini dilakukan dengan menggunakan reset()
untuk memulai dengan daftar ABI kosong, diikuti oleh include
dengan daftar ABI yang masing-masing mendapatkan APK.
Groovy
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. enable true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include "x86", "x86_64" // Specifies that you don't want to also generate a universal APK that includes all ABIs. universalApk false } } }
Kotlin
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. isEnable = true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include("x86", "x86_64") // Specifies that you don't want to also generate a universal APK that includes all ABIs. isUniversalApk = false } } }
Untuk daftar ABI yang didukung, lihat ABI yang Didukung.
Project tanpa kode native/C++
Untuk project tanpa kode native/C++, panel Build Variants memiliki dua kolom: Module dan Active Build Variant, seperti ditunjukkan pada gambar 1.
Gambar 1. Panel Build Variants memiliki dua kolom untuk project tanpa
kode native/C++.
Nilai Active Build Variant untuk modul menentukan varian build yang di-deploy dan terlihat di editor. Untuk beralih antarvarian, klik sel Active Build Variant untuk modul lalu pilih varian yang diinginkan dari kolom daftar.
Project dengan kode native/C++
Untuk project dengan kode native/C++, panel Build Variants memiliki tiga kolom: Module, Active Build Variant, dan Active ABI, seperti yang ditunjukkan pada gambar 2.
Gambar 2. Panel Build Variants menambahkan kolom Active ABI untuk project dengan kode native/C++.
Nilai Active Build Variant untuk modul menentukan varian build yang di-deploy dan terlihat di editor. Untuk modul native, nilai Active ABI akan menentukan ABI yang digunakan editor, tetapi tidak memengaruhi varian yang di-deploy.
Untuk mengubah jenis build atau ABI:
- Klik sel untuk kolom Active Build Variant atau Active ABI.
- Pilih varian atau ABI yang diinginkan dari kolom daftar. Sinkronisasi baru akan otomatis berjalan.
Mengubah kolom untuk aplikasi maupun modul library akan menerapkan perubahan untuk semua baris dependen.
Mengonfigurasi pembuatan versi
Secara default, saat Gradle menghasilkan multi-APK, setiap APK memiliki
informasi versi yang sama, seperti yang ditentukan dalam
file build.gradle
atau build.gradle.kts
level modul. Karena
Google Play Store tidak mengizinkan multi-APK untuk aplikasi yang sama jika semuanya memiliki
informasi versi yang sama, Anda harus memastikan bahwa setiap APK memiliki
versionCode
unik sebelum menguploadnya ke Play Store.
Anda dapat mengonfigurasi file build.gradle
tingkat modul untuk
mengganti versionCode
untuk setiap APK. Dengan membuat pemetaan
yang menetapkan nilai numerik unik untuk setiap ABI dan kepadatan yang dikonfigurasi
multi-APK, Anda dapat mengganti kode versi output dengan nilai yang
menggabungkan kode versi yang ditentukan dalam blok defaultConfig
atau
productFlavors
dengan nilai numerik yang ditetapkan ke
kepadatan atau ABI.
Pada contoh berikut, APK untuk ABI x86
mendapatkan versionCode
2004 dan ABI x86_64
mendapatkan versionCode
3004.
Menetapkan kode versi dalam peningkatan besar, seperti 1000, memungkinkan
Anda menetapkan kode versi unik di lain waktu jika Anda perlu mengupdate aplikasi. Misalnya, jika defaultConfig.versionCode
mengiterasi ke 5 dalam
update berikutnya, Gradle akan menetapkan versionCode
2005 ke
APK x86
dan 3005 ke APK x86_64
.
Tips: Jika build Anda menyertakan APK universal, tetapkan
versionCode
yang lebih rendah daripada APK lain mana pun.
Karena Google Play Store menginstal versi aplikasi Anda yang kompatibel dengan perangkat target dan yang memiliki versionCode
tertinggi, menetapkan versionCode
yang lebih rendah ke APK universal akan memastikan bahwa Google Play Store mencoba menginstal salah satu APK Anda sebelum menggantinya ke APK universal. Kode contoh berikut
menangani hal ini dengan tidak mengganti versionCode
default
APK universal.
Groovy
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // Map for the version code that gives each ABI a value. ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3] // For per-density APKs, create a similar map: // ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 3] import com.android.build.OutputFile // For each APK output variant, override versionCode with a combination of // ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. android.applicationVariants.all { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.each { output -> // Stores the value of ext.abiCodes that is associated with the ABI for this variant. def baseAbiVersionCode = // Determines the ABI for this variant and returns the mapped value. project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiVersionCode != null) { // Assigns the new version code to versionCodeOverride, which changes the // version code for only the output APK, not for the variant itself. Skipping // this step causes Gradle to use the value of variant.versionCode for the APK. output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode } } }
Kotlin
android { ... defaultConfig { ... versionCode = 4 } splits { ... } } // Map for the version code that gives each ABI a value. val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3) // For per-density APKs, create a similar map: // val densityCodes = mapOf("mdpi" to 1, "hdpi" to 2, "xhdpi" to 3) import com.android.build.api.variant.FilterConfiguration.FilterType.* // For each APK output variant, override versionCode with a combination of // abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. androidComponents { onVariants { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == ABI }?.identifier // Stores the value of abiCodes that is associated with the ABI for this variant. val baseAbiCode = abiCodes[name] // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiCode != null) { // Assigns the new version code to output.versionCode, which changes the version code // for only the output APK, not for the variant itself. output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0)) } } } }
Untuk contoh skema kode versi alternatif lainnya, lihat Menetapkan kode versi.
Membuat beberapa APK
Setelah Anda mengonfigurasi file build.gradle
atau
build.gradle.kts
tingkat modul untuk mem-build multi-APK, klik
Build > Build APK untuk mem-build semua APK untuk modul yang saat ini
dipilih di panel Project. Gradle membuat APK
untuk setiap kepadatan atau ABI dalam direktori build/outputs/apk/
project.
Gradle akan membuat APK untuk setiap kepadatan atau ABI yang multi APK-nya Anda konfigurasi. Jika Anda mengaktifkan multi-APK untuk kepadatan dan ABI, Gradle akan membuat APK untuk setiap kombinasi kepadatan dan ABI.
Misalnya, cuplikan
build.gradle
berikut memungkinkan pembuatan multi-APK untuk kepadatan mdpi
dan
hdpi
, serta ABI x86
dan x86_64
:
Groovy
... splits { density { enable true reset() include "mdpi", "hdpi" } abi { enable true reset() include "x86", "x86_64" } }
Kotlin
... splits { density { isEnable = true reset() include("mdpi", "hdpi") } abi { isEnable = true reset() include("x86", "x86_64") } }
Output dari contoh konfigurasi ini mencakup 4 APK berikut:
app-hdpiX86-release.apk
: Berisi kode dan resource untuk kepadatanhdpi
dan ABIx86
.app-hdpiX86_64-release.apk
: Berisi kode dan resource untuk kepadatanhdpi
dan ABIx86_64
.app-mdpiX86-release.apk
: Berisi kode dan resource untuk kepadatanmdpi
dan ABIx86
.app-mdpiX86_64-release.apk
: Berisi kode dan resource untuk kepadatanmdpi
dan ABIx86_64
.
Saat membuat multi-APK berdasarkan kepadatan layar, Gradle akan selalu menghasilkan APK universal yang mencakup kode dan resource untuk semua kepadatan, selain APK untuk setiap kepadatan.
Saat membuat multi-APK berdasarkan
ABI, Gradle hanya menghasilkan APK yang menyertakan kode dan resource untuk semua
ABI jika Anda menentukan universalApk true
dalam
blok splits.abi
di file build.gradle
(untuk Groovy) atau isUniversalApk = true
dalam
blok splits.abi
di file build.gradle.kts
(untuk skrip Kotlin).
Format nama file APK
Saat membuat multi-APK, Gradle menghasilkan nama file APK menggunakan skema berikut:
modulename-screendensityABI-buildvariant.apk
Komponen skemanya adalah:
-
modulename
- Menentukan nama modul yang dibuat.
-
screendensity
-
Menentukan kepadatan layar untuk APK, misalnya
mdpi
, jika multi-APK untuk kepadatan layar diaktifkan. -
ABI
-
Menentukan ABI untuk APK, seperti
x86
, jika multi-APK untuk ABI diaktifkan.Jika multi-APK untuk kepadatan layar dan ABI diaktifkan, Gradle akan menyambungkan nama kepadatan dengan nama ABI, misalnya
mdpiX86
. JikauniversalApk
diaktifkan untuk APK per ABI, Gradle akan menggunakanuniversal
sebagai bagian ABI dari nama file APK universal. -
buildvariant
-
Menentukan varian build yang sedang di-build, seperti
debug
.
Misalnya, saat mem-build APK kepadatan layar mdpi
untuk
versi debug myApp, nama file APK adalah
myApp-mdpi-debug.apk
. Versi
rilis myApp yang dikonfigurasi untuk membuat multi-APK untuk kepadatan layar mdpi
dan ABI x86
memiliki nama file APK dari
myApp-mdpiX86-release.apk
.