Waktu build yang lama memperlambat proses pengembangan. Halaman ini menjelaskan beberapa teknik untuk membantu Anda mengatasi kendala kecepatan build.
Proses yang biasa dilakukan untuk meningkatkan kecepatan build Anda adalah sebagai berikut:
- Mengoptimalkan konfigurasi build dengan menjalankan beberapa langkah yang langsung memberikan manfaat pada sebagian besar project Android Studio.
- Membuat profil build untuk mengidentifikasi dan mendiagnosis beberapa kendala rumit yang mungkin berlaku spesifik pada project atau workstation Anda.
Saat mengembangkan aplikasi, sebaiknya Anda melakukan deployment ke perangkat yang menjalankan Android 7.0 (API level 24) atau lebih baru, jika memungkinkan. Platform Android versi baru menggunakan mekanisme yang lebih baik untuk mendorong update ke aplikasi Anda, seperti Android Runtime (ART) dan dukungan native untuk beberapa file DEX.
Catatan: Setelah membuat clean build pertama, Anda mungkin merasa bahwa build selanjutnya—clean dan incremental—berperforma jauh lebih cepat (bahkan tanpa menggunakan pengoptimalan apa pun yang dijelaskan pada halaman ini). Itu karena daemon Gradle memiliki periode "pemanasan" untuk meningkatkan performa—serupa dengan proses JVM lainnya.
Mengoptimalkan konfigurasi build Anda
Ikuti tips berikut untuk meningkatkan kecepatan build project Android Studio Anda.
Menjaga alat agar selalu terupdate
Hampir setiap update Android menghadirkan pengoptimalan build dan fitur-fitur baru. Beberapa tips pada halaman ini diberikan dengan asumsi bahwa Anda menggunakan Android versi terbaru. Untuk memanfaatkan pengoptimalan terbaru, selalu update:
Membuat varian build untuk pengembangan
Banyak dari konfigurasi yang Anda perlukan saat menyiapkan aplikasi untuk dirilis sebenarnya tidak diperlukan saat mengembangkan aplikasi. Mengaktifkan proses build yang tidak diperlukan akan memperlambat build clean dan inkremental, jadi konfigurasikan varian build yang hanya mempertahankan konfigurasi build yang diperlukan saat mengembangkan aplikasi. Contoh berikut membuat ragam "dev" dan "prod" (untuk konfigurasi versi rilis Anda):
Groovy
android { ... defaultConfig {...} buildTypes {...} productFlavors { // When building a variant that uses this flavor, the following configurations // override those in the defaultConfig block. dev { // To avoid using legacy multidex when building from the command line, // set minSdkVersion to 21 or higher. When using Android Studio 2.3 or higher, // the build automatically avoids legacy multidex when deploying to a device running // API level 21 or higher—regardless of what you set as your minSdkVersion. minSdkVersion 21 versionNameSuffix "-dev" applicationIdSuffix '.dev' } prod { // If you've configured the defaultConfig block for the release version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to create this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } }
Kotlin
android { ... defaultConfig {...} buildTypes {...} productFlavors { // When building a variant that uses this flavor, the following configurations // override those in the defaultConfig block. create("dev") { // To avoid using legacy multidex when building from the command line, // set minSdkVersion to 21 or higher. When using Android Studio 2.3 or higher, // the build automatically avoids legacy multidex when deploying to a device running // API level 21 or higher—regardless of what you set as your minSdkVersion. minSdkVersion(21) versionNameSuffix = "-dev" applicationIdSuffix = ".dev" } create("prod") { // If you've configured the defaultConfig block for the release version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to create this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } }
Jika konfigurasi build sudah menggunakan ragam produk untuk membuat versi aplikasi yang berbeda, Anda dapat menggabungkan konfigurasi "dev" dan "prod" dengan ragam tersebut menggunakan dimensi ragam. Misalnya, jika sudah mengonfigurasi ragam "demo" dan "full", Anda dapat menggunakan contoh konfigurasi berikut untuk membuat gabungan ragam, seperti "devDemo" dan "prodFull":
Groovy
android { ... defaultConfig {...} buildTypes {...} // Specifies the flavor dimensions you want to use. The order in which you // list each dimension determines its 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 "stage", "mode" productFlavors { dev { dimension "stage" minSdkVersion 21 versionNameSuffix "-dev" applicationIdSuffix '.dev' ... } prod { dimension "stage" ... } demo { dimension "mode" ... } full { dimension "mode" ... } } }
Kotlin
android { ... defaultConfig {...} buildTypes {...} // Specifies the flavor dimensions you want to use. The order in which you // list each dimension determines its 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("stage", "mode") productFlavors { create("dev") { dimension = "stage" minSdkVersion(21) versionNameSuffix = "-dev" applicationIdSuffix = ".dev" ... } create("prod") { dimension = "stage" ... } create("demo") { dimension = "mode" ... } create("full") { dimension = "mode" ... } } }
Sinkronisasi project varian tunggal
Menyinkronkan project dengan konfigurasi build merupakan langkah penting yang akan memungkinkan Android Studio memahami struktur project. Namun, untuk project besar, proses ini dapat membutuhkan waktu lama. Jika project Anda menggunakan beberapa varian build, Android Studio akan mengoptimalkan sinkronisasi project dengan membatasinya hanya pada varian yang saat ini Anda pilih.
Pengoptimalan ini diaktifkan secara default pada semua project dan tidak dapat dikonfigurasi lagi pada Android Studio versi 4.2 dan yang lebih baru.
Untuk mengaktifkan pengoptimalan ini secara manual, Anda harus menggunakan Android Studio 3.3 atau yang lebih baru dengan Android Gradle Plugin 3.3.0 atau yang lebih baru. Klik File > Settings > Experimental > Gradle (Android Studio > Preferences > Experimental > Gradle di Mac), lalu centang kotak Only sync the active variant.
Catatan: Pengoptimalan ini sepenuhnya mendukung project yang menggunakan bahasa Java dan C++, serta menyediakan dukungan tertentu untuk Kotlin. Jika Anda mengaktifkan pengoptimalan untuk project berkonten Kotlin, sinkronisasi Gradle akan melakukan fallback dan menggunakan varian lengkap secara internal.
Menghindari kompilasi resource yang tidak perlu
Hindari mengompilasi dan mengemas resource yang tidak sedang Anda uji (seperti pelokalan bahasa tambahan dan resource kepadatan layar). Anda dapat melakukannya dengan hanya menetapkan satu resource bahasa dan kepadatan layar untuk ragam "dev", seperti yang ditunjukkan pada contoh berikut:
Groovy
android { ... productFlavors { dev { ... // The following configuration limits the "dev" flavor to using // English stringresources and xxhdpi screen-density resources. resConfigs "en", "xxhdpi" } ... } }
Kotlin
android { ... productFlavors { create("dev") { ... // The following configuration limits the "dev" flavor to using // English stringresources and xxhdpi screen-density resources. resConfigs("en", "xxhdpi") } ... } }
Menonaktifkan Crashlytics untuk build debug Anda
Jika Anda tidak perlu menjalankan laporan Crashlytics, percepat proses build debug dengan menonaktifkan plugin ini melalui cara berikut:
Groovy
android { ... buildTypes { debug { ext.enableCrashlytics = false } } }
Kotlin
android { ... buildTypes { getByName("debug") { extra["enableCrashlytics"] = false } } }
Anda juga harus menonaktifkan kit Crashlytics saat runtime untuk build debug dengan mengubah cara inisialisasi dukungan Fabric di aplikasi, seperti yang ditunjukkan di bawah ini:
Kotlin
// Initializes Fabric for builds that don't use the debug build type. Crashlytics.Builder() .core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()) .build() .also { crashlyticsKit -> Fabric.with(this, crashlyticsKit) }
Java
// Initializes Fabric for builds that don't use the debug build type. Crashlytics crashlyticsKit = new Crashlytics.Builder() .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()) .build(); Fabric.with(this, crashlyticsKit);
Menonaktifkan pembuatan ID build otomatis
Jika ingin menggunakan Crashlytics dengan build debug, Anda tetap dapat mempercepat build incremental dengan mencegah Crashlytics mengupdate resource aplikasi dengan ID build uniknya sendiri selama setiap proses build. Karena ID build ini disimpan dalam file resource yang direferensikan oleh manifes, penonaktifan pembuatan ID build otomatis juga memungkinkan Anda untuk menggunakan opsi Terapkan Perubahan bersama Crashlytics untuk build debug Anda.
Agar Crashlytics tidak otomatis mengupdate ID build-nya, tambahkan
berikut ini ke file build.gradle
:
Groovy
android { ... buildTypes { debug { ext.alwaysUpdateBuildId = false } } }
Kotlin
android { ... buildTypes { getByName("debug") { extra["alwaysUpdateBuildId"] = false } } }
Untuk mengetahui cara mengoptimalkan build selagi menggunakan Crashlytics selengkapnya, baca dokumentasi resmi.
Menggunakan nilai konfigurasi build statis dengan build debug
Selalu gunakan nilai statis/hard-code untuk properti yang dimasukkan ke file manifes atau file resource untuk jenis build debug.
Misalnya, penggunaan kode versi dinamis, nama versi, resource, atau
logika build lain yang mengubah file manifes memerlukan build aplikasi
lengkap setiap kali Anda ingin menjalankan perubahan—meskipun perubahan sebenarnya mungkin
hanya memerlukan hot swap. Jika konfigurasi build Anda memerlukan
properti dinamis tersebut, maka pisahkan konfigurasi tersebut ke varian build rilis Anda dan pertahankan
nilai statis untuk build debug. Untuk contoh, lihat
seperti yang ditunjukkan pada file
build.gradle
di bawah.
Groovy
int MILLIS_IN_MINUTE = 1000 * 60 int minutesSinceEpoch = System.currentTimeMillis() / MILLIS_IN_MINUTE android { ... defaultConfig { // Making either of these two values dynamic in the defaultConfig will // require a full app build and reinstallation because the AndroidManifest.xml // must be updated. versionCode 1 versionName "1.0" ... } // The defaultConfig values above are fixed, so your incremental builds don't // need to rebuild the manifest (and therefore the whole app, slowing build times). // But for release builds, it's okay. So the following script iterates through // all the known variants, finds those that are "release" build types, and // changes those properties to something dynamic. applicationVariants.all { variant -> if (variant.buildType.name == "release") { variant.mergedFlavor.versionCode = minutesSinceEpoch; variant.mergedFlavor.versionName = minutesSinceEpoch + "-" + variant.flavorName; } } }
Kotlin
val MILLIS_IN_MINUTE = 1000 * 60 val minutesSinceEpoch = System.currentTimeMillis() / MILLIS_IN_MINUTE android { ... defaultConfig { // Making either of these two values dynamic in the defaultConfig will // require a full app build and reinstallation because the AndroidManifest.xml // must be updated. versionCode = 1 versionName = "1.0" ... } // The defaultConfig values above are fixed, so your incremental builds don't // need to rebuild the manifest (and therefore the whole app, slowing build times). // But for release builds, it's okay. So the following script iterates through // all the known variants, finds those that are "release" build types, and // changes those properties to something dynamic. applicationVariants.forEach { variant -> if (variant.buildType.name == "release") { variant.mergedFlavor.versionCode = minutesSinceEpoch variant.mergedFlavor.versionName = minutesSinceEpoch + "-" + variant.flavorName } } }
Menggunakan versi dependensi statis
Saat mendeklarasikan dependensi dalam file build.gradle
, sebaiknya
jangan menambahkan tanda plus di belakang nomor versi, seperti
'com.android.tools.build:gradle:2.+'
. Penggunaan nomor versi dinamis
dapat menyebabkan update versi tidak terduga, kesulitan mengatasi perbedaan versi,
dan build lebih lambat karena ada pemeriksaan update oleh Gradle. Sebagai gantinya,
sebaiknya Anda menggunakan nomor versi statis/hard-code.
Membuat modul library
Temukan kode dalam aplikasi Anda yang dapat diubah menjadi modul library Android. Memodulasi kode dengan cara ini memungkinkan sistem build untuk hanya mengompilasi modul yang Anda ubah, dan meng-cache output tersebut untuk build mendatang. Tindakan ini juga membuat eksekusi project paralel jadi lebih efektif (saat Anda mengaktifkan pengoptimalan tersebut).
Membuat tugas untuk logika build kustom
Setelah membuat profil build, jika fase "Mengonfigurasi
Project" ternyata menghabiskan
waktu build yang cukup lama, periksa skrip build.gradle
dan cari
kode yang dapat Anda sertakan dalam tugas Gradle kustom. Dengan memindahkan beberapa logika build
ke dalam sebuah tugas, kode hanya akan dijalankan saat diperlukan, hasilnya dapat di-cache untuk
build selanjutnya, dan logika build tersebut dapat dijalankan secara paralel
(jika Anda menjalankan eksekusi project paralel). Untuk mempelajari lebih lanjut, baca
dokumentasi resmi Gradle.
Tips: Jika build Anda menyertakan banyak tugas kustom, Anda mungkin
perlu memecah file build.gradle
dengan membuat class tugas kustom. Tambahkan class Anda ke
direktori project-root/buildSrc/src/main/groovy/
dan
Gradle akan memasukkannya secara otomatis ke dalam classpath
untuk semua file build.gradle
di project Anda.
Mengonversi gambar ke WebP
WebP adalah format file gambar yang memberikan kompresi lossy (seperti JPEG) serta transparansi (seperti PNG), tetapi dapat memberikan kompresi yang lebih baik daripada JPEG atau PNG. Mengurangi ukuran file gambar, tanpa perlu menjalankan kompresi waktu-build, dapat mempercepat build, terutama jika aplikasi Anda menggunakan banyak referensi gambar. Namun, Anda mungkin akan melihat sedikit peningkatan penggunaan CPU perangkat saat melakukan dekompresi gambar WebP. Melalui Android Studio, Anda dapat mengonversi gambar ke WebP dengan mudah.
Menonaktifkan pemrosesan PNG
Jika tidak dapat (atau tidak ingin) mengonversi gambar
PNG ke WebP, Anda tetap dapat mempercepat build dengan menonaktifkan kompresi
gambar otomatis setiap kali mem-build aplikasi. Jika Anda menggunakan
plugin Android 3.0.0 atau yang lebih baru,
pemroresan PNG dinonaktifkan secara default hanya untuk jenis build "debug". Guna menonaktifkan
pengoptimalan ini untuk jenis build lainnya, tambahkan kode berikut ini ke file build.gradle
Anda:
Groovy
android { buildTypes { release { // Disables PNG crunching for the release build type. crunchPngs false } } // If you're using an older version of the plugin, use the // following: // aaptOptions { // cruncherEnabled false // } }
Kotlin
android { buildTypes { getByName("release") { // Disables PNG crunching for the release build type. isCrunchPngs = false } } // If you're using an older version of the plugin, use the // following: // aaptOptions { // cruncherEnabled = false // } }
Karena jenis build atau ragam produk tidak menentukan properti ini, Anda perlu
menyetel properti ini secara manual ke true
saat membuat versi
rilis aplikasi Anda.
Menggunakan pemroses anotasi inkremental
Plugin Android Gradle 3.3.0 dan yang lebih baru meningkatkan dukungan untuk pemrosesan anotasi inkremental. Jadi, untuk meningkatkan kecepatan build inkremental, Anda perlu mengupdate plugin Android Gradle dan hanya menggunakan pemroses anotasi inkremental jika memungkinkan.
Catatan: Fitur ini kompatibel dengan Gradle versi 4.10.1 dan versi yang lebih baru, kecuali untuk Gradle 5.1 (lihat Masalah Gradle #8194).
Untuk memulai, lihat tabel pemroses anotasi populer berikut ini yang mendukung pemrosesan anotasi inkremental. Untuk daftar lebih lengkap, baca Status dukungan dalam pemroses anotasi populer. Beberapa pemroses anotasi mungkin memerlukan langkah tambahan untuk mengaktifkan pengoptimalan, jadi pastikan untuk membaca dokumentasi setiap pemroses anotasi.
Selain itu, jika Anda menggunakan Kotlin di aplikasi, Anda harus menggunakan kapt 1.3.30 dan versi yang lebih baru untuk mendukung pemroses anotasi inkremental untuk kode Kotlin Anda. Pastikan untuk membaca dokumentasi resmi guna mengetahui apakah Anda perlu mengaktifkan perilaku ini secara manual atau tidak.Perlu diingat, jika Anda harus menggunakan satu atau beberapa pemroses anotasi yang tidak mendukung incremental build, pemrosesan anotasi tidak akan bertambah. Namun, jika project Anda menggunakan kapt, kompilasi Java masih bersifat inkremental.
Dukungan pemroses anotasi inkremental
Nama project | Nama class pemroses anotasi | Didukung sejak ... |
---|---|---|
DataBinding | android.databinding.annotationprocessor.ProcessDataBinding | AGP 3.5 |
Room | androidx.room.RoomProcessor | 2.3.0-alpha02
2.20: Gunakan opsi room.incremental .
|
ButterKnife | butterknife.compiler.ButterKnifeProcessor | 10.2.0 |
Glide | com.bumptech.glide.annotation.compiler.GlideAnnotationProcessor | 4.9.0 |
Dagger | dagger.internal.codegen.ComponentProcessor | 2.18 |
Lifecycle | androidx.lifecycle.LifecycleProcessor | 2.2.0-alpha02 |
AutoService | com.google.auto.service.processor.AutoServiceProcessor | 1.0-rc7 |
Dagger | dagger.android.processor.AndroidProcessor | 2.18 |
Realm | io.realm.processor.RealmProcessor | 5.11.0 |
Lombok | lombok.launch.AnnotationProcessorHider$AnnotationProcessor | 1.16.22 |
Lombok | lombok.launch.AnnotationProcessorHider$ClaimingProcessor | 1.16.22 |
Mengonfigurasi pembersih sampah JVM
Performa build dapat ditingkatkan dengan mengonfigurasi pembersih sampah JVM optimal yang digunakan oleh Gradle. Meskipun JDK 8 dikonfigurasi untuk menggunakan pembersih sampah paralel secara default, JDK 9 dan yang lebih tinggi dikonfigurasi untuk menggunakan pembersih sampah G1.
Untuk meningkatkan performa build, sebaiknya
uji build Gradle Anda dengan pembersih sampah
paralel. Di gradle.properties
tetapkan hal berikut:
org.gradle.jvmargs=-XX:+UseParallelGC
Jika ada opsi lain yang telah ditetapkan di kolom ini, tambahkan opsi baru:
org.gradle.jvmargs=-Xmx1536m -XX:+UseParallelGC
Untuk mengukur kecepatan build dengan konfigurasi yang berbeda, lihat Membuat profil build Anda.
Menggunakan class R non-transitif
Anda harus menggunakan class R non-transitif agar memiliki build yang lebih cepat untuk aplikasi dengan beberapa modul. Cara ini membantu mencegah duplikasi resource dengan memastikan bahwa class R setiap modul hanya berisi referensi ke resource-nya sendiri, tanpa mengambil referensi dari dependensinya. Dengan demikian, build menjadi lebih cepat dan Anda dapat menghindari kompilasi terkait.
Mulai dari Android Studio Bumblebee, class R non-transitif diaktifkan secara default untuk project baru. Untuk project yang dibuat dengan versi Studio sebelumnya, Anda dapat mengupdatenya agar menggunakan class R non-transitif dengan membuka Refactor > Migrate to Non-Transitive R Classes.
Untuk mempelajari lebih lanjut tentang resource aplikasi dan class R, lihat Ringkasan resource aplikasi.
Menonaktifkan flag Jetifier
Sebagian besar project menggunakan library AndroidX secara langsung sehingga Anda mungkin dapat menghapus
flag Jetifier untuk performa build yang lebih baik. Untuk menghapus
pemeriksaan Jetifier, tetapkan android.enableJetifier=false
dalam
file gradle.properties
Anda. Build Analyzer dapat melakukan pemeriksaan untuk melihat apakah flag dapat
dihapus dengan aman agar project Anda memiliki performa build yang lebih baik dan bermigrasi dari
Android Support library yang tidak dikelola. Untuk mempelajari lebih lanjut tentang Build Analyzer, lihat
Memecahkan masalah performa build.
Menggunakan cache konfigurasi (eksperimental)
Cache konfigurasi adalah fitur eksperimental yang memungkinkan Gradle merekam informasi tentang grafik tugas build dan menggunakannya kembali dalam build berikutnya, sehingga tidak perlu mengonfigurasi ulang seluruh build. Untuk mengaktifkan cache konfigurasi, ikuti langkah-langkah berikut:
- Periksa apakah semua plugin project kompatibel. Gunakan Build Analyzer untuk memeriksa apakah project Anda kompatibel dengan cache konfigurasi. Fitur ini menjalankan urutan build pengujian untuk menentukan apakah fitur ini dapat diaktifkan untuk project tersebut. Anda juga dapat melihat masalah #13490 untuk daftar plugin yang didukung.
Tambahkan kode berikut ke file
gradle.properties
:org.gradle.unsafe.configuration-cache=true # Use this flag sparingly, in case some of the plugins are not fully compatible org.gradle.unsafe.configuration-cache-problems=warn
- Saat cache konfigurasi diaktifkan, saat pertama kali Anda menjalankan project, output build
akan menampilkan
Calculating task graph as no configuration cache is available for tasks
. Selama eksekusi berikutnya, output build akan menampilkanReusing configuration cache
.