Membuat beberapa APK

Meskipun sebaiknya buat satu APK untuk mendukung semua perangkat target Anda kapan pun memungkinkan, hal itu dapat menghasilkan APK yang sangat besar karena file yang mendukung beberapa Antarmuka Biner Aplikasi (ABI). Salah satu cara untuk mengurangi ukuran APK adalah dengan membuat beberapa APK yang berisi file untuk ABI tertentu.

Gradle dapat membuat APK terpisah yang hanya berisi kode dan resource khusus untuk setiap ABI. Halaman ini menjelaskan cara mengonfigurasi build untuk membuat beberapa APK. Jika Anda perlu membuat versi aplikasi yang berbeda yang tidak didasarkan pada ABI, gunakan varian build.

Mengonfigurasi build untuk multi-APK

Untuk mengonfigurasi build untuk beberapa APK, tambahkan blok splits ke file build.gradle level modul. Dalam blok splits, sediakan blok abi yang menentukan cara Anda ingin Gradle membuat APK per ABI.

Mengonfigurasi multi-APK untuk ABI

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

Opsi Gradle DSL berikut digunakan untuk mengonfigurasi multi-APK untuk setiap 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 ABI yang dipisahkan koma yang tidak ingin Anda buatkan APK terpisah oleh Gradle. Gunakan exclude jika Anda ingin membuat APK untuk sebagian besar ABI, tetapi perlu mengecualikan beberapa ABI yang tidak didukung oleh aplikasi Anda.
reset()

Menghapus daftar default ABI. Hanya gunakan jika digabungkan dengan elemen include untuk menentukan ABI yang ingin Anda tambahkan.

Cuplikan berikut menetapkan daftar ABI hanya ke x86 dan x86_64 dengan memanggil reset() untuk menghapus daftar, 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 ABI yang dipisahkan koma yang ingin Anda buatkan APK-nya oleh Gradle. Hanya gunakan bersama dengan reset() untuk menentukan daftar ABI yang tepat.

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 satu APK. Nilai defaultnya adalah false.

Contoh berikut 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 akan 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 mengetahui 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 yang ditunjukkan pada gambar 1.

Panel Build Variants memiliki dua kolom untuk project tanpa kode native/C++.
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 Anda inginkan 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.

Panel Varian Build menambahkan kolom Active ABI untuk project dengan kode native/C++.
Gambar 2. Panel Varian Build 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 oleh editor, tetapi tidak memengaruhi varian build yang di-deploy.

Untuk mengubah jenis build atau ABI:

  1. Klik sel untuk kolom varian build aktif atau ABI aktif.
  2. Pilih varian atau ABI yang Anda pilih 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 beberapa 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 beberapa APK untuk aplikasi yang sama yang semuanya memiliki informasi versi yang sama, Anda harus memastikan bahwa setiap APK memiliki versionCode yang unik sebelum 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 yang Anda konfigurasi beberapa APK-nya, 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 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 menetapkan kode versi unik nanti jika perlu mengupdate aplikasi. Misalnya, jika defaultConfig.versionCode melakukan iterasi ke 5 dalam update berikutnya, Gradle akan menetapkan versionCode 2005 ke APK x86 dan 3005 ke APK x86_64.

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]

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)

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 mengonfigurasi file build.gradle atau build.gradle.kts level 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 ABI di direktori build/outputs/apk/ project.

Gradle akan mem-build APK untuk setiap ABI yang Anda konfigurasi untuk beberapa APK.

Misalnya, cuplikan build.gradle berikut memungkinkan pembuatan beberapa APK untuk ABI x86 dan x86_64:

Groovy

...
  splits {
    abi {
      enable true
      reset()
      include "x86", "x86_64"
    }
  }

Kotlin

...
  splits {
    abi {
      isEnable = true
      reset()
      include("x86", "x86_64")
    }
  }

Output dari contoh konfigurasi ini mencakup 4 APK berikut:

  • app-X86-release.apk: Berisi kode dan resource untuk ABI x86.
  • app-X86_64-release.apk: Berisi kode dan resource untuk ABI x86_64.

Saat mem-build beberapa APK berdasarkan ABI, Gradle hanya akan menghasilkan APK yang menyertakan kode dan resource untuk semua ABI jika Anda menentukan universalApk true di blok splits.abi dalam file build.gradle (untuk Groovy) atau isUniversalApk = true di blok splits.abi dalam file build.gradle.kts (untuk skrip Kotlin).

Format nama file APK

Saat mem-build beberapa APK, Gradle akan menghasilkan nama file APK menggunakan skema berikut:

modulename-ABI-buildvariant.apk

Komponen skemanya adalah:

modulename
Menentukan nama modul yang sedang di-build.
ABI
Jika beberapa APK untuk ABI diaktifkan, tentukan ABI untuk APK, seperti x86.
buildvariant
Menentukan varian build yang sedang dibuat, seperti debug.