Membuat beberapa APK

Perhatian: Sejak Agustus 2021, semua aplikasi harus dipublikasikan sebagai App Bundle. Jika Anda memublikasikan aplikasi ke Google Play, membuat dan mengupload Android App Bundle. Kapan Anda melakukannya, Google Play otomatis membuat dan menayangkan APK yang dioptimalkan untuk konfigurasi perangkat setiap pengguna, sehingga mereka hanya mengunduh kode dan sumber daya yang mereka perlukan untuk menjalankan aplikasi Anda. Memublikasikan multi-APK 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 membuat satu APK untuk mendukung semua perangkat target Anda jika memungkinkan, hal itu dapat menghasilkan APK yang sangat besar karena file mendukung beberapa kepadatan layar atau Biner Aplikasi Antarmuka (ABI). Salah satu cara untuk mengurangi ukuran APK adalah dengan membuat multi-APK yang berisi file untuk ABI atau kepadatan layar 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 berbagai versi aplikasi 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. Di dalam splits memblokir, menyediakan blok density yang menentukan cara Gradle dibuat APK per kepadatan atau blok abi yang menentukan cara Gradle diinginkan untuk membuat APK per ABI. Anda dapat menyediakan blok kepadatan dan ABI, serta sistem build akan membuat APK untuk setiap kombinasi kepadatan dan ABI.

Mengonfigurasi multi-APK untuk kepadatan layar

Untuk membuat APK terpisah bagi kepadatan layar yang berbeda, tambahkan density blok di dalam Pemblokiran splits. Di blok density Anda, berikan daftar kepadatan layar yang diinginkan dan ukuran layar yang kompatibel. Hanya gunakan daftar ukuran layar yang kompatibel jika Anda memerlukan <compatible-screens> di 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 adalah false.
exclude
Menentukan daftar yang dipisahkan koma untuk kepadatan yang tidak Anda inginkan dari Gradle yang akan dibuat APK terpisah. 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 hanya bila dikombinasikan dengan Elemen include untuk menentukan kepadatan yang ingin Anda tambahkan.

Cuplikan berikut menetapkan daftar kepadatan hanya untuk ldpi dan xxhdpi dengan memanggil reset() untuk menghapus daftar, lalu menggunakan include:

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 Anda inginkan untuk dibuat oleh Gradle APK untuk. Hanya gunakan bersama reset() untuk menentukan daftar kepadatan yang tepat.
compatibleScreens

Menentukan daftar dipisahkan koma untuk ukuran layar yang kompatibel. Hal ini memasukkan yang cocok <compatible-screens> di manifes untuk setiap APK.

Setelan ini memberikan cara mudah untuk mengelola kedua layar kepadatan dan ukuran layar di bagian build.gradle yang sama. Namun, menggunakan <compatible-screens> dapat membatasi jenis perangkat aplikasi Anda. Cara alternatif untuk mendukung berbagai ukuran layar, lihat ringkasan kompatibilitas layar.

Karena setiap APK yang didasarkan pada kepadatan layar menyertakan Tag <compatible-screens> dengan batasan spesifik jenis layar yang didukung APK—meskipun Anda memublikasikan beberapa APK—beberapa perangkat baru tidak cocok dengan filter beberapa APK Anda. Dengan demikian, Gradle selalu membuat APK universal tambahan yang berisi aset untuk semua kepadatan layar dan tidak menyertakan Tag <compatible-screens>. Publikasikan ini APK universal beserta APK untuk setiap kepadatan guna menyediakan fallback bagi perangkat yang tidak cocok dengan APK dengan Tag <compatible-screens>.

Contoh berikut menghasilkan APK terpisah untuk masing-masing layar kepadatan tertentu kecuali ldpi, xxhdpi, dan xxxhdpi. Hal ini dilakukan dengan menggunakan exclude untuk menghapus ketiga kepadatan tersebut dari daftar {i> default<i} 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 build varian aplikasi Anda pada jenis layar dan perangkat tertentu, lihat Menyatakan pembatasan dukungan layar.

Mengonfigurasi multi-APK untuk ABI

Guna membuat APK terpisah untuk ABI berbeda, tambahkan blok abi di dalam blok splits Anda. Di blok abi Anda, berikan daftar ABI yang diinginkan.

Opsi Gradle DSL berikut digunakan untuk mengonfigurasi multi-APK per ABI:

enable untuk Groovy, atau isEnable untuk skrip Kotlin
Jika Anda menetapkan elemen ini ke true, Gradle akan menghasilkan beberapa APK berdasarkan ABI yang Anda tentukan. Nilai defaultnya adalah false.
exclude
Menentukan daftar dipisahkan koma untuk ABI yang tidak Anda inginkan untuk Gradle untuk membuat APK terpisah. Gunakan exclude jika Anda ingin membuat APK untuk sebagian besar ABI, tetapi perlu mengecualikan beberapa ABI yang tidak digunakan aplikasi Anda dukungan teknis IT.
reset()

Mengosongkan daftar default ABI. Gunakan hanya bila dikombinasikan dengan include untuk menentukan ABI yang ingin Anda tambahkan.

Cuplikan berikut menetapkan daftar ABI hanya ke x86 dan x86_64 dengan memanggil reset() untuk mengosongkan daftar, dan lalu menggunakan include:

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 Anda inginkan agar dibuat APK oleh Gradle untuk mereka. Gunakan opsi ini hanya jika dikombinasikan dengan reset() untuk menentukan nilai yang tepat daftar ABI.
universalApk untuk Groovy, atau isUniversalApk untuk Skrip Kotlin

Jika true, Gradle akan menghasilkan APK universal selain APK per ABI. APK universal berisi kode dan resource untuk semua ABI dalam APK tunggal. Nilai defaultnya adalah false.

Perhatikan bahwa opsi ini hanya tersedia di blok splits.abi. Saat membuat multi-APK berdasarkan kepadatan layar, Gradle selalu menghasilkan APK universal yang berisi kode dan sumber daya untuk semua kepadatan layar.

Contoh berikut akan menghasilkan APK terpisah untuk setiap ABI: x86 dan x86_64. Hal ini dilakukan 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 Didukung ABI.

Project tanpa kode native/C++

Untuk project tanpa kode native/C++, panel Build Variants memiliki dua kolom: Module dan Active Build Varian, seperti yang ditunjukkan pada gambar 1.


Panel varian Build Gambar 1. Panel Build Variants memiliki dua kolom untuk project tanpa kode native/C++.

Nilai Active Build Variant untuk menentukan varian build yang di-deploy dan terlihat di editor. Untuk beralih antarvarian, klik sel Active Build Variant untuk modul dan 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 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, tetapi tidak memengaruhi apa yang di-deploy.

Untuk mengubah jenis build atau ABI:

  1. Klik sel untuk Active Build Variant atau Active ABI.
  2. Pilih varian atau ABI yang diinginkan dari daftar kolom tersebut. Sinkronisasi baru akan otomatis berjalan.

Mengubah kolom untuk aplikasi atau modul library akan menerapkan perubahan untuk semua baris dependen.

Mengonfigurasi pembuatan versi

Secara default, saat Gradle menghasilkan multi-APK, setiap APK memiliki informasi versi, seperti yang dijelaskan dalam File build.gradle atau build.gradle.kts. Karena Google Play Store tidak mengizinkan multi-APK untuk aplikasi yang sama yang semuanya memiliki informasi versi yang sama, Anda perlu memastikan bahwa setiap APK memiliki versionCode sebelum Anda menguploadnya ke Play Store.

Anda dapat mengonfigurasi file build.gradle level modul untuk mengganti versionCode untuk setiap APK. Dengan membuat pemetaan yang menetapkan nilai numerik unik untuk setiap ABI dan kepadatan yang Anda konfigurasikan multi-APK, Anda dapat mengganti kode versi output dengan nilai yang menggabungkan kode versi yang ditentukan dalam defaultConfig atau productFlavors dengan nilai numerik yang ditetapkan ke kepadatan atau ABI.

Dalam contoh berikut, APK untuk ABI x86 mendapatkan versionCode 2004 dan ABI x86_64 mendapatkan versionCode 3004.

Menetapkan kode versi dalam penambahan besar, seperti 1000, memungkinkan Anda untuk menetapkan kode versi unik di lain waktu jika Anda perlu mengupdate aplikasi. Sebagai misalnya, jika defaultConfig.versionCode melakukan iterasi ke 5 dalam update berikutnya, Gradle menetapkan versionCode 2005 untuk APK x86 dan 3005 ke APK x86_64.

Tips: Jika build Anda menyertakan APK universal, tetapkan versionCode yang lebih rendah dari APK Anda yang lain. 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.

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 build.gradle level modul atau build.gradle.kts file untuk membangun multi-APK, klik Buat > Build APK untuk membangun semua APK untuk yang dipilih di panel Project. Gradle membuat APK untuk setiap kepadatan atau ABI dalam build/outputs/apk/ project saat ini.

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 memungkinkan pembuatan multi-APK untuk mdpi dan kepadatan 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 kepadatan hdpi dan ABI x86.
  • app-hdpiX86_64-release.apk: Berisi kode dan resource untuk kepadatan hdpi dan ABI x86_64.
  • app-mdpiX86-release.apk: Berisi kode dan resource untuk kepadatan mdpi dan ABI x86.
  • app-mdpiX86_64-release.apk: Berisi kode dan resource untuk kepadatan mdpi dan ABI x86_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 membangun multi-APK berdasarkan ABI, Gradle hanya menghasilkan APK yang menyertakan kode dan resource untuk semua ABI jika Anda menentukan universalApk true dalam direktori Blok splits.abi di file build.gradle Anda (untuk Groovy) atau isUniversalApk = true di Blok splits.abi di file build.gradle.kts (untuk skrip Kotlin).

Format nama file APK

Saat membangun multi-APK, Gradle menghasilkan nama file APK menggunakan skema:

modulename-screendensityABI-buildvariant.apk

Komponen skemanya adalah:

modulename
Menentukan nama modul yang dibuat.
screendensity
Menentukan layar jika multi-APK untuk kepadatan layar diaktifkan kepadatan untuk APK, seperti mdpi.
ABI

Menentukan ABI untuk APK, seperti jika multi-APK untuk ABI diaktifkan, sebagai x86.

Jika multi-APK untuk kepadatan layar dan ABI diaktifkan, Gradle menyambungkan nama kepadatan dengan nama ABI, misalnya mdpiX86. Jika universalApk diaktifkan untuk per-ABI APK, Gradle menggunakan universal sebagai bagian ABI dari APK universal .

buildvariant
Menentukan varian build yang sedang dibuat, seperti debug.

Misalnya, saat membuat APK kepadatan layar mdpi untuk versi debug myApp, nama file APK-nya adalah myApp-mdpi-debug.apk. Rilis myApp yang dikonfigurasi untuk membangun multi-APK untuk aplikasi Kepadatan layar mdpi dan ABI x86 memiliki nama file APK myApp-mdpiX86-release.apk.