Sebagai penulis library, Anda harus memastikan bahwa developer aplikasi dapat dengan mudah memasukkan library Anda ke dalam aplikasi mereka sekaligus mempertahankan pengalaman pengguna akhir yang berkualitas tinggi. Anda harus memastikan bahwa library Anda kompatibel dengan pengoptimalan Android tanpa penyiapan tambahan—atau mendokumentasikan bahwa library mungkin tidak sesuai untuk digunakan di Android.
Dokumentasi ini ditujukan untuk developer library yang dipublikasikan, tetapi mungkin juga berguna bagi developer modul library internal dalam aplikasi besar yang dimodularisasi.
Jika Anda adalah developer aplikasi dan ingin mempelajari cara mengoptimalkan aplikasi Android, lihat Mengaktifkan pengoptimalan aplikasi. Untuk mempelajari library yang sesuai untuk digunakan, lihat Memilih library dengan bijak.
Menggunakan codegen daripada refleksi
Jika memungkinkan, gunakan pembuatan kode (codegen) daripada refleksi. Codegen dan refleksi adalah pendekatan umum untuk menghindari kode boilerplate saat memprogram, tetapi codegen lebih kompatibel dengan pengoptimal aplikasi seperti R8:
- Dengan codegen, kode dianalisis dan diubah selama proses build. Karena tidak ada modifikasi besar setelah waktu kompilasi, pengoptimal mengetahui kode yang pada akhirnya diperlukan dan kode yang dapat dihapus dengan aman.
- Dengan refleksi, kode dianalisis dan dimanipulasi saat runtime. Karena kode tidak benar-benar selesai hingga dieksekusi, pengoptimal tidak tahu kode apa saja yang dapat dihapus dengan aman. Tindakan ini kemungkinan akan menghapus kode yang digunakan secara dinamis melalui refleksi selama runtime, yang menyebabkan error aplikasi bagi pengguna.
Banyak library modern menggunakan codegen, bukan refleksi. Lihat KSP untuk titik entri umum, yang digunakan oleh Room, Dagger2, dan banyak lagi.
Saat refleksi diizinkan
Jika harus menggunakan refleksi, Anda hanya boleh memantulkan ke salah satu hal berikut:
- Jenis yang ditargetkan secara spesifik (penerapkan antarmuka atau subclass tertentu)
- Kode yang menggunakan anotasi runtime tertentu
Menggunakan refleksi dengan cara ini akan membatasi biaya runtime, dan memungkinkan penulisan aturan penyimpanan konsumen yang ditargetkan.
Bentuk refleksi spesifik dan tertarget ini adalah pola yang dapat Anda lihat di framework Android (misalnya saat meng-inflate aktivitas, tampilan, dan drawable) dan library AndroidX (misalnya saat membuat WorkManager ListenableWorkers, atau RoomDatabases). Sebaliknya, refleksi terbuka Gson tidak sesuai untuk digunakan di aplikasi Android.
Menulis aturan simpan konsumen
Library harus memaketkan aturan keep "konsumen", yang menggunakan format yang sama dengan aturan keep aplikasi. Aturan ini dipaketkan ke dalam artefak library (AAR atau JAR) dan digunakan secara otomatis selama pengoptimalan aplikasi Android saat library digunakan.
Library AAR
Untuk menambahkan aturan konsumen untuk library AAR, gunakan opsi consumerProguardFiles
dalam skrip build modul library Android. Untuk informasi selengkapnya, lihat
panduan kami tentang membuat modul library.
Kotlin
android { defaultConfig { consumerProguardFiles("consumer-proguard-rules.pro") } ... }
Groovy
android { defaultConfig { consumerProguardFiles 'consumer-proguard-rules.pro' } ... }
Library JAR
Untuk memaketkan aturan dengan library Kotlin/Java yang dikirim sebagai JAR, tempatkan
file aturan Anda di direktori META-INF/proguard/
JAR akhir, dengan nama file apa pun.
Misalnya, jika kode Anda berada di <libraryroot>/src/main/kotlin
, tempatkan file aturan konsumen
di
<libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro
dan aturan akan dipaketkan di lokasi yang benar dalam JAR output Anda.
Pastikan JAR final memaketkan aturan dengan benar dengan memeriksa apakah aturan tersebut
ada di direktori META-INF/proguard
.
Mendukung berbagai penyingkat (lanjutan)
Anda dapat menyesuaikan aturan ke penyingkat tertentu yang ditargetkan (R8 atau ProGuard), serta versi penyingkat tertentu. Hal ini memungkinkan library Anda berfungsi secara optimal dalam project yang menggunakan versi penyingkat baru, sekaligus memungkinkan aturan yang ada terus digunakan dalam project dengan versi penyingkat yang lebih lama.
Untuk menentukan aturan penyingkatan yang ditargetkan, Anda harus menyertakannya di lokasi tertentu di dalam library AAR atau JAR, seperti yang dijelaskan di bawah.
In an AAR library:
consumer-proguard-rules.pro (legacy location)
classes.jar
└── META-INF
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
In a JAR library:
META-INF
├── proguard/<ProGuard-rules-file> (legacy location)
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
Artinya, aturan penyingkatan yang ditargetkan disimpan di direktori META-INF/com.android.tools
JAR atau di direktori META-INF/com.android.tools
di dalam
classes.jar
AAR.
Di direktori tersebut, dapat ada beberapa direktori dengan nama dalam bentuk
r8-from-<X>-upto-<Y>
atau proguard-from-<X>-upto-<Y>
untuk menunjukkan
versi shrinker yang aturannya ditulis di dalam direktori.
Perhatikan bahwa bagian -from-<X>
dan -upto-<Y>
bersifat opsional, versi <Y>
eksklusif, dan rentang versi harus berkelanjutan.
Misalnya, r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0
, dan r8-from-8.2.0
membentuk
kumpulan aturan penyingkatan yang ditargetkan yang valid. Aturan di bawah
direktori r8-from-8.0.0-upto-8.2.0
akan digunakan oleh R8 dari versi 8.0.0 hingga
tetapi tidak termasuk versi 8.2.0.
Dengan informasi tersebut, plugin Android Gradle akan memilih aturan dari
direktori R8 yang cocok. Jika library tidak menentukan aturan penyingkatan yang ditargetkan,
plugin Android Gradle akan memilih aturan dari lokasi lama
(proguard.txt
untuk AAR atau META-INF/proguard/<ProGuard-rules-file>
untuk
JAR).