Membuat multi-APK

Jika memublikasikan aplikasi ke Google Play, sebaiknya Anda membuat dan mengupload Android App Bundle. Setelah Anda melakukannya, Google Play akan menghasilkan dan menayangkan APK yang dioptimalkan untuk setiap konfigurasi perangkat pengguna secara otomatis, sehingga pengguna hanya mendownload kode dan resource yang mereka perlukan untuk menjalankan aplikasi Anda. Memublikasikan multi-APK akan berguna jika Anda tidak memublikasikan aplikasi ke Google Play. Namun untuk itu Anda harus membuat, menandatangani, dan mengelola sendiri setiap APK.

Meskipun, jika memungkinkan, Anda sebaiknya membuat satu APK untuk mendukung semua perangkat target, hal tersebut dapat menghasilkan APK yang sangat besar karena adanya file yang diperlukan untuk mendukung berbagai kepadatan layar atau Application Binary Interface (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 untuk menghasilkan multi-APK. Jika perlu membuat beberapa versi lain dari aplikasi Anda yang tidak didasarkan pada kepadatan layar atau ABI, Anda dapat menggunakan varian build.

Mengonfigurasi build untuk multi-APK

Agar build Anda dapat menggunakan multi-APK, tambahkan blok splits ke file build.gradle tingkat modul. Di dalam blok splits, sediakan blok density yang menentukan bagaimana Gradle akan menghasilkan APK untuk setiap kepadatan, atau blok abi yang menentukan bagaimana Gradle akan menghasilkan APK untuk setiap ABI. Anda dapat menyediakan blok kepadatan dan blok ABI, dan sistem build akan membuat sebuah APK untuk setiap kombinasi kepadatan dan ABI.

Mengonfigurasi multi-APK untuk kepadatan layar

Jika ingin membuat APK terpisah untuk berbagai kepadatan layar, tambahkan blok density di dalam blok splits. Di blok density, cantumkan kepadatan layar yang diinginkan dan ukuran layar yang kompatibel. Daftar ukuran layar yang kompatibel hanya boleh digunakan jika Anda memerlukan elemen <compatible-screens> yang spesifik di setiap manifes APK.

Opsi Gradle DSL berikut digunakan untuk mengonfigurasi multi-APK untuk kepadatan layar:

enable
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 dipisahkan koma untuk kepadatan yang APK terpisahnya tidak perlu dihasilkan oleh Gradle. Gunakan exclude jika Anda ingin menghasilkan 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 ke ldpi dan xxhdpi saja dengan memanggil reset() untuk mengosongkan daftar, kemudian menggunakan include.
    reset()  // Clears the default list from all densities to no densities.
    include "ldpi", "xxhdpi" // Specifies the two densities we want to generate APKs for.
    
include
Menentukan daftar dipisahkan koma untuk kepadatan yang APK-nya perlu dihasilkan oleh Gradle. Gunakan opsi ini hanya jika dikombinasikan dengan reset() untuk menentukan daftar pasti kepadatan.
compatibleScreens
Menentukan daftar dipisahkan koma untuk ukuran layar yang kompatibel. Opsi ini akan memasukkan node <compatible-screens> yang cocok ke dalam manifes untuk setiap APK. Setelan ini memberikan cara mudah untuk mengelola kepadatan layar dan juga ukuran layar di bagian build.gradle yang sama. Namun, penggunaan <compatible-screens> dapat membatasi jenis perangkat yang dapat menjalankan aplikasi Anda. Untuk cara alternatif mendukung berbagai ukuran layar, baca Mendukung Banyak Layar.

Karena setiap APK yang didasarkan pada kepadatan layar menyertakan tag <compatible-screens> dengan pembatasan khusus terkait jenis layar mana yang didukung APK, meskipun Anda memublikasikan multi-APK, beberapa perangkat baru tidak akan cocok dengan beberapa filter APK Anda. Karena itu, Gradle selalu membuat APK universal tambahan yang berisi aset untuk semua kepadatan layar dan tidak menyertakan tag <compatible-screens>. Sebaiknya Anda memublikasikan APK universal ini bersama dengan APK untuk setiap kepadatan guna menyediakan fallback bagi perangkat yang tidak cocok dengan APK yang menyertakan tag <compatible-screens>.

Contoh berikut menghasilkan APK terpisah untuk setiap kepadatan layar yang tercantum dalam Rentang layar yang didukung, kecuali ldpi, xxhdpi, dan xxxhdpi. Ini dilakukan menggunakan exclude untuk menghapus tiga kepadatan dari daftar default semua kepadatan.

    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 Gradle should not 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 daftar nama kepadatan dan nama ukuran layar, lihat Cara Mendukung Banyak Layar. Untuk detail selengkapnya tentang mendistribusikan aplikasi Anda ke perangkat dan jenis layar tertentu, lihat Mendistribusikan ke Layar Tertentu.

Mengonfigurasi multi-APK untuk ABI

Jika Anda perlu membuat APK terpisah untuk ABI berbeda, tambahkan blok abi ke dalam blok splits Anda. Dalam blok abi Anda, cantumkan ABI yang diinginkan.

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

enable
Jika Anda menetapkan elemen ini ke true, Gradle akan menghasilkan multi-APK berdasarkan ABI yang Anda tetapkan. Nilai defaultnya adalah false.
exclude
Menentukan daftar dipisahkan koma untuk ABI yang APK terpisahnya tidak perlu dihasilkan oleh Gradle. Gunakan exclude jika Anda ingin membuat APK untuk sebagian besar ABI, tetapi perlu mengecualikan beberapa ABI yang tidak didukung aplikasi Anda.
reset()
Mengosongkan daftar default ABI. Gunakan opsi ini hanya jika dikombinasikan dengan elemen include untuk menentukan ABI yang ingin Anda tambahkan. Cuplikan berikut menetapkan daftar ABI ke x86 dan x86_64 saja dengan memanggil reset() untuk mengosongkan daftar, kemudian 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 dipisahkan koma untuk ABI yang APK-nya perlu dihasilkan oleh Gradle. Gunakan opsi ini jika dikombinasikan dengan reset() untuk menentukan daftar pasti ABI.
universalApk
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 adalah false. Perhatikan bahwa opsi ini hanya tersedia di blok splits.abi. Saat membuat multi-APK berdasarkan kepadatan layar, Gradle selalu membuat APK universal yang berisi kode dan resource untuk semua kepadatan layar.

Contoh berikut menghasilkan APK terpisah untuk setiap ABI: x86 dan x86_64. Ini dilakukan menggunakan reset() untuk memulai dengan daftar kosong ABI, diikuti dengan include yang berisi daftar ABI yang masing-masing akan mendapatkan APK.

    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 we only
          // want APKs for x86 and x86_64.

          // Resets the list of ABIs that Gradle should create APKs for to none.
          reset()

          // Specifies a list of ABIs that Gradle should create APKs for.
          include "x86", "x86_64"

          // Specifies that we do not want to also generate a universal APK that includes all ABIs.
          universalApk false
        }
      }
    }
    

Untuk daftar ABI yang didukung, lihat ABI yang Didukung.

mips, mips64, dan armeabi

Android Gradle Plugin 3.1.0 dan yang lebih tinggi tidak lagi menghasilkan APK untuk ABI berikut secara default: mips, mips64, dan armeabi. Hal itu karena NDK r17 dan yang lebih tinggi tidak lagi menyertakan ABI ini sebagai target yang didukung.

Pertimbangkan untuk terlebih dahulu memeriksa Konsol Google Play untuk memverifikasi bahwa ada pengguna yang mendownload APK aplikasi Anda yang menargetkan ABI ini. Jika tidak, sebaiknya Anda menghilangkannya dari build Anda. Jika ingin terus membuat APK yang menargetkan ABI ini, Anda harus menggunakan NDK r16b atau yang lebih lama dan menentukan ABI dalam file build.gradle, seperti ditunjukkan di bawah ini:

    splits {
        abi {
            include 'armeabi', 'mips', 'mips64'
            ...
        }
    }
    

Masalah Umum: Jika menggunakan Android Gradle Plugin 3.0.1 atau yang lebih rendah dengan NDK r17 atau yang lebih tinggi, Anda mungkin mendapatkan error berikut: Error:ABIs [mips64, armeabi, mips] are not supported for platform. Hal itu karena versi lama plugin ini masih menyertakan ABI yang secara default tidak didukung saat Anda membuat APK untuk setiap ABI. Untuk mengatasi masalah ini, update plugin ke versi terbaru, atau, dalam file build.gradle aplikasi Anda, setel ulang daftar default plugin untuk ABI dan sertakan hanya ABI yang didukung yang Anda inginkan, seperti ditunjukkan di bawah ini:

    ...
    splits {
        abi {
            ...
            reset()
            include "x86", "armeabi-v7a", "arm64-v8a", "x86_64"
        }
    }
    

Mengonfigurasi pembuatan versi

Secara default, saat Gradle menghasilkan multi-APK, setiap APK akan memiliki informasi versi yang sama, seperti yang ditentukan dalam file build.gradle tingkat modul. Karena Google Play Store tidak mengizinkan multi-APK untuk aplikasi yang sama jika semuanya memiliki informasi versi yang sama, Anda harus memastikan setiap APK memiliki versionCode yang unik sebelum menguploadnya ke Play Store.

Anda dapat mengonfigurasi file build.gradle tingkat modul untuk mengganti versionCode setiap APK. Dengan membuat pemetaan yang menetapkan nilai numerik unik untuk setiap ABI dan kepadatan yang multi APK-nya Anda konfigurasi, 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.

Dalam contoh berikut, APK untuk ABI x86 akan mendapatkan versionCode 2004, sedangkan ABI x86_64 mendapatkan kode versi 3004. Dengan menetapkan kode versi dalam kenaikan besar, seperti 1000, Anda akan dapat menetapkan kode versi unik di lain waktu jika perlu mengupdate aplikasi. Misalnya, jika defaultConfig.versionCode mengiterasi ke 5 pada update berikutnya, Gradle akan menetapkan versionCode 2005 ke APK x86 dan kode versi 3005 ke APK x86_64.

Tips: Jika build Anda menyertakan APK universal, Anda harus memberinya versionCode yang lebih rendah daripada APK lain mana pun. Karena Google Play Store menginstal versi aplikasi yang kompatibel dengan perangkat target dan juga memiliki versionCode tertinggi, penetapan versionCode yang lebih rendah ke APK universal akan memastikan bahwa Google Play Store mencoba menginstal salah satu APK Anda sebelum melakukan fallback ke APK universal. Kode contoh di bawah menangani hal ini dengan tidak mengganti versionCode default pada APK universal.

    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 like this:
    // 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 does not override the version code for universal APKs.
        // However, because we 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 simply
          // causes Gradle to use the value of variant.versionCode for the APK.
          output.versionCodeOverride =
                  baseAbiVersionCode * 1000 + variant.versionCode
        }
      }
    }
    

Untuk contoh skema kode versi alternatif lainnya, lihat Menetapkan kode versi.

Membuat multi-APK

Setelah Anda mengonfigurasi file build.gradle tingkat modul untuk membuat multi-APK, klik Build > Build APK untuk membuat semua APK bagi modul yang saat ini dipilih di panel Project. Gradle akan membuat APK untuk setiap kepadatan atau ABI ke 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 juga 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, dan juga ABI x86 dan x86_64.

    ...
      splits {
        density {
          enable true
          reset()
          include "mdpi", "hdpi"
        }
        abi {
          enable 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 saja.
  • app-hdpiX86_64-release.apk: Berisi kode dan resource untuk kepadatan hdpi dan ABI x86_64 saja.
  • app-mdpiX86-release.apk: Berisi kode dan resource untuk kepadatan mdpi dan ABI x86 saja.
  • app-mdpiX86_64-release.apk: Berisi kode dan resource untuk kepadatan mdpi dan ABI x86_64 saja.

Saat membuat multi-APK berdasarkan kepadatan layar, Gradle 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 pada blok splits.abi dalam file build.gradle Anda.

Format nama file APK

Saat membuat multi-APK, Gradle menggunakan nama file APK yang 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, misalnya "x86", jika multi-APK untuk ABI diaktifkan. Jika multi-APK untuk kepadatan layar dan juga ABI diaktifkan, Gradle akan merangkai nama kepadatan dengan nama ABI, misalnya "mdpiX86". Jika universalApk diaktifkan untuk APK per ABI, Gradle akan menggunakan "universal" sebagai bagian ABI dari nama file APK universal.
buildvariant
Menentukan varian build yang sedang dibuat, misalnya "debug".

Sebagai contoh, saat membuat APK kepadatan layar mdpi untuk versi debug "myApp", maka nama file APK-nya adalah myApp-mdpi-debug.apk. Versi rilis "myApp" yang dikonfigurasi untuk membuat multi-APK bagi kepadatan layar mdpi dan ABI x86 memiliki nama file APK myApp-mdpiX86-release.apk.