Saat menggunakan aturan keep, penting untuk mencapai jumlah kekhususan yang tepat untuk memastikan Anda melihat manfaatnya sekaligus mempertahankan perilaku aplikasi. Lihat bagian berikut untuk mempelajari pola yang baik serta hal-hal yang harus dihindari dalam aturan penyimpanan.
Pola yang baik dalam aturan keep
Aturan penyimpanan yang ditentukan dengan baik bersifat sespesifik mungkin dan mematuhi pola berikut:
Untuk spesifikasi class, selalu tentukan class, class dasar, atau class yang dianotasi jika memungkinkan, seperti yang ditunjukkan dalam contoh berikut:
-keepclassmembers class com.example.MyClass { void someSpecificMethod(); }-keepclassmembers ** extends com.example.MyBaseClass { void someSpecificMethod(); }-keepclassmembers @com.example.MyAnnotation class ** { void someSpecificMethod(); }Jika memungkinkan, gunakan anotasi pada kode sumber Anda, lalu targetkan anotasi tersebut secara langsung dalam aturan penyimpanan Anda. Hal ini akan membuat link yang jelas dan eksplisit antara kode Anda dan aturan yang mempertahankannya, sehingga membuat konfigurasi Anda lebih tangguh, lebih mudah dipahami, dan tidak terlalu rentan terhadap kerusakan saat kode berubah.
Misalnya, cuplikan berikut menunjukkan cara mempertahankan class MyClass, serta class lain yang dianotasi dengan
@com.example.DisplayComponent:// In the source code @com.example.DisplayComponent class MyClass { /* ... */ } // In the keep rules -keep @com.example.DisplayComponent class * {*;}Sebaiknya beri nama anotasi Anda sehingga memberikan konteks yang bermakna tentang alasan bagian kode dipertahankan. Misalnya, gunakan
@DisplayComponentuntuk aplikasi yang komponen tampilannya memerlukan beberapa bagian untuk dipertahankan.Jika memungkinkan, spesifikasi anggota harus dideklarasikan, dan hanya mereferensikan bagian class yang harus dipertahankan agar aplikasi dapat berfungsi. Sebaiknya jangan terapkan aturan ke seluruh class dengan menentukan cakupan anggota opsional sebagai
{ *; }kecuali jika benar-benar diperlukan.-keepclassmembers com.example.MyClass { void someSpecificMethod(); void @com.example.MyAnnotation *; }Jika Anda menggunakan opsi global
repackageclasses, hindari menentukan nama paket opsional. Hal ini menghasilkan file DEX yang lebih kecil karena awalan paket dihilangkan dalam nama class yang dipaketkan ulang.Pertahankan aturan penyimpanan untuk semua item yang diakses oleh refleksi. Meskipun item tersebut dipertahankan oleh R8 tanpa aturan penyimpanan yang eksplisit, mempertahankan aturan sebenarnya sangat penting karena perubahan kode di masa mendatang dapat menyebabkan R8 tidak lagi mempertahankan item ini.
Untuk refleksi dalam kode Anda sendiri, Anda dapat menggunakan Jetpack Keep untuk membuat aturan keep yang lebih mudah dikelola. Setiap anotasi berada pada kode yang melakukan refleksi, sehingga saat Anda mengubah kode tersebut, Anda memperbarui atau menghapus anotasinya di tempat yang sama. Dengan demikian, aturan tidak mempertahankan kode yang tidak lagi direfleksikan oleh aplikasi Anda. Lint juga menandai panggilan reflektif yang tidak dianotasi.
Jika memungkinkan, gunakan
-assumenosideeffectsatau-convertchecknotnulluntuk mengoptimalkan pemeriksaan null karena hal ini dapat mengurangi ukuran DEX aplikasi Anda secara signifikan. Untuk mengetahui informasi selengkapnya, lihat Jenis aturan tambahan.
Jika tidak dapat mematuhi pedoman ini, Anda dapat mengisolasi kode yang perlu dipertahankan dalam paket khusus untuk sementara dan menerapkan aturan penyimpanan ke paket tersebut. Namun, hal ini bukan solusi jangka panjang. Untuk mempelajari lebih lanjut, lihat Menerapkan pengoptimalan secara bertahap. Untuk menggunakan aturan penyimpanan untuk paket, tentukan aturan penyimpanan seperti yang ditunjukkan dalam contoh berikut:
-keepclassmembers class com.example.pkg.** { *; }
Hal yang perlu dihindari
Sintaksis aturan penyimpanan memiliki banyak opsi, tetapi untuk manfaat performa berkelanjutan yang terukur, sebaiknya jangan gunakan opsi berikut:
- Jangan gunakan aturan penyimpanan seluruh paket seperti
-keep class com.example.pkg.** { *; }dalam jangka panjang. Opsi ini dapat digunakan sementara untuk mengatasi masalah saat mengonfigurasi R8. Untuk mengetahui informasi selengkapnya, lihat Membatasi cakupan pengoptimalan. Secara umum, berhati-hatilah dengan karakter pengganti—pastikan Anda hanya menyimpan kode yang Anda butuhkan. - Jika memungkinkan, hindari penggunaan library yang menyarankan Anda menyalin dan menempelkan aturan penyimpanan saat menggunakannya, terutama aturan penyimpanan di seluruh paket. Library yang didesain agar berperforma baik di Android harus menghindari refleksi jika memungkinkan dan menyematkan aturan penyimpanan konsumen jika diperlukan.
- Hindari penggunaan operator inversi
!dalam aturan keep karena Anda dapat menerapkan aturan secara tidak sengaja ke hampir setiap class dalam aplikasi.
Jika Anda tidak dapat mengikuti aturan ini, Anda mungkin menggunakan banyak refleksi yang tidak terbatas, dan harus menghindari refleksi atau menghindari penggunaan library dengan refleksi (lihat studi kasus Gson).