Untuk mengaktifkan pengoptimalan aplikasi, Anda harus menggunakan library yang kompatibel dengan pengoptimalan Android. Jika library tidak dikonfigurasi untuk pengoptimalan Android—misalnya, jika menggunakan refleksi tanpa memaketkan aturan keep terkait—library tersebut mungkin tidak cocok untuk aplikasi Android. Halaman ini menjelaskan alasan beberapa library lebih cocok untuk pengoptimalan aplikasi dan memberikan tips umum untuk membantu Anda memilih.
Memilih codegen daripada refleksi
Umumnya, Anda harus memilih library yang menggunakan pembuatan kode (codegen), bukan refleksi. Dengan codegen, pengoptimal dapat lebih mudah menentukan kode yang sebenarnya digunakan saat runtime dan kode yang dapat dihapus. Sulit untuk mengetahui apakah library menggunakan codegen atau refleksi, tetapi ada beberapa tanda—lihat tips untuk mendapatkan bantuan.
Untuk mengetahui informasi selengkapnya tentang codegen versus refleksi, lihat Pengoptimalan untuk penulis library.
Tips umum saat memilih library
Gunakan tips ini untuk membantu memastikan bahwa library Anda kompatibel dengan pengoptimalan aplikasi.
Memeriksa masalah pengoptimalan
Saat mempertimbangkan library baru, lihat pelacak masalah dan diskusi online library untuk memeriksa apakah ada masalah terkait minifikasi atau mengonfigurasi pengoptimalan aplikasi. Jika ada, Anda harus mencoba mencari alternatif untuk library tersebut. Ingat hal berikut:
- Library AndroidX dan library seperti Hilt berfungsi dengan baik dengan optimasi aplikasi karena menggunakan codegen, bukan refleksi. Saat menggunakan refleksi, mereka memberikan aturan penyimpanan minimum untuk hanya menyimpan kode yang diperlukan.
- Library serialisasi sering menggunakan refleksi untuk menghindari kode boilerplate saat membuat instance atau melakukan serialisasi objek. Daripada pendekatan berbasis refleksi (seperti Gson untuk JSON), cari library yang menggunakan codegen untuk menghindari masalah ini, misalnya dengan menggunakan Serialisasi Kotlin.
- Library yang menyertakan aturan keep seluruh paket harus dihindari jika memungkinkan. Aturan keep seluruh paket dapat membantu menyelesaikan error, tetapi aturan keep yang luas pada akhirnya harus ditingkatkan kualitasnya agar hanya menyimpan kode yang diperlukan. Untuk mengetahui informasi selengkapnya, lihat Mengimplementasikan pengoptimalan secara bertahap.
Mengaktifkan pengoptimalan setelah menambahkan library baru
Saat Anda menambahkan library baru, aktifkan pengoptimalan setelahnya dan periksa apakah ada error. Jika ada error, cari alternatif untuk library tersebut atau tulis aturan keep. Jika library tidak kompatibel dengan pengoptimalan, laporkan bug dengan library tersebut.
Aturan bersifat kumulatif
Perhatikan bahwa aturan simpan bersifat aditif. Artinya, aturan tertentu yang disertakan dependensi library tidak dapat dihapus dan dapat memengaruhi kompilasi bagian lain aplikasi Anda. Misalnya, jika library menyertakan aturan untuk menonaktifkan pengoptimalan kode, aturan tersebut akan menonaktifkan pengoptimalan untuk seluruh project Anda.
Memeriksa penggunaan refleksi (lanjutan)
Anda mungkin dapat mengetahui apakah library menggunakan refleksi dari pemeriksaan kodenya. Jika library menggunakan refleksi, pastikan library tersebut menyediakan aturan keep yang terkait. Library mungkin menggunakan refleksi jika melakukan hal berikut:
- Menggunakan class atau metode dari paket
kotlin.reflect
ataujava.lang.reflect
- Menggunakan fungsi
Class.forName
atauclassLoader.getClass
- Membaca anotasi saat runtime, misalnya jika menyimpan nilai anotasi
menggunakan
val value = myClass.getAnnotation()
atauval value = myMethod.getAnnotation()
, lalu melakukan sesuatu denganvalue
Memanggil metode menggunakan nama metode sebagai string, misalnya:
// Calls the private `processData` API with reflection myObject.javaClass.getMethod("processData", DataType::class.java) ?.invoke(myObject, data)
Memfilter aturan simpan yang buruk (lanjutan)
Anda harus menghindari library dengan aturan keep yang mempertahankan kode yang benar-benar harus dihapus. Namun, jika harus menggunakannya, Anda dapat memfilter aturan seperti yang ditunjukkan dalam kode berikut:
// If you're using AGP 8.4 and higher
buildTypes {
release {
optimization.keepRules {
it.ignoreFrom("com.somelibrary:somelibrary")
}
}
}
// If you're using AGP 7.3-8.3
buildTypes {
release {
optimization.keepRules {
it.ignoreExternalDependencies("com.somelibrary:somelibrary")
}
}
}
Studi kasus: Alasan Gson mengalami error dengan pengoptimalan
Gson adalah library serialisasi yang sering menyebabkan masalah pada pengoptimalan aplikasi
karena banyak menggunakan refleksi. Cuplikan kode berikut menunjukkan cara Gson
biasanya digunakan, yang dapat dengan mudah menyebabkan error saat runtime. Perhatikan bahwa saat menggunakan Gson untuk mendapatkan daftar objek Pengguna, Anda tidak memanggil konstruktor atau meneruskan factory ke fungsi fromJson()
. Membuat atau menggunakan class yang ditentukan
aplikasi tanpa salah satu dari hal berikut adalah tanda bahwa library mungkin menggunakan
refleksi terbuka:
- Class aplikasi yang mengimplementasikan library, atau antarmuka atau class standar
- Plugin pembuatan kode seperti KSP
class User(val name: String)
class UserList(val users: List<User>)
// This code runs in debug mode, but crashes when optimizations are enabled
Gson().fromJson("""[{"name":"myname"}]""", User::class.java).toString()
Saat R8 menganalisis kode ini dan tidak melihat UserList
atau User
yang dibuat instance-nya
di mana pun, R8 dapat mengganti nama kolom, atau menghapus konstruktor yang tampaknya tidak
digunakan, sehingga menyebabkan aplikasi Anda error. Jika Anda menggunakan library lain dengan cara
yang serupa, Anda harus memeriksa apakah library tersebut tidak akan mengganggu pengoptimalan aplikasi, dan jika
ya, hindari library tersebut.
Perhatikan bahwa Room dan Hilt keduanya membuat jenis yang ditentukan aplikasi, tetapi menggunakan codegen untuk menghindari kebutuhan akan refleksi.