Menambahkan aturan simpan

Saat Anda mengaktifkan pengoptimalan aplikasi dengan setelan default, R8 akan melakukan pengoptimalan yang ekstensif untuk memaksimalkan manfaat performa Anda. R8 membuat perubahan substansial pada kode, termasuk mengganti nama, memindahkan, dan menghapus kolom dan metode class. Jika hal ini menyebabkan error, Anda perlu menentukan bagian kode mana yang tidak akan dihapus dengan menulis aturan keep.

R8 mungkin salah menghapus atau mengubah kode dalam situasi berikut:

  • Refleksi: kode yang diakses menggunakan refleksi, misalnya menggunakan Class.forName() atau Method.invoke(). R8 biasanya tidak dapat mengetahui class atau metode mana yang akan diakses dengan cara ini.
  • Serialisasi: class atau kolom yang diperlukan untuk serialisasi dan deserialisasi mungkin tampak tidak digunakan untuk R8 (ini adalah bentuk refleksi lainnya).
  • Java Native Interface (JNI): Metode Java yang dipanggil dari kode native. R8 tidak menganalisis kode native untuk melihat apa yang mungkin dipanggil kembali ke Java.

Halaman ini membahas cara membatasi tingkat pengoptimalan R8. Untuk mempelajari cara menyesuaikan resource yang disimpan, lihat Menambahkan aturan penyimpanan untuk resource.

Tempat untuk menambahkan aturan penyimpanan

Anda harus menambahkan aturan ke file proguard-rules.pro yang berada di direktori root modul (file mungkin sudah ada, tetapi jika belum, buat file tersebut). Untuk menerapkan aturan dalam file, Anda harus mendeklarasikan file dalam file build.gradle.kts (atau build.gradle) level modul seperti yang ditunjukkan dalam kode berikut:

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // File with your custom rules.
                "proguard-rules.pro"
            )
            ...
        }
    }
    ...
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile('proguard-android-optimize.txt'),

                // File with your custom rules.
                'proguard-rules.pro'
            )
        }
    }
    // ...
}

Secara default, skrip build Anda juga menyertakan file proguard-android-optimize.txt. File ini menyertakan aturan yang diperlukan untuk sebagian besar project Android, sehingga Anda harus menyimpannya dalam skrip build.

Cara menulis aturan keep

Selama kompilasi aplikasi, R8 mendeteksi kode yang perlu disimpan dalam aplikasi dengan menganalisis grafik panggilan aplikasi, yang dimulai dari entri manifes (seperti aktivitas atau layanan) dan melacak setiap aplikasi dan panggilan fungsi library. R8 menghapus kode yang tidak direferensikan secara langsung dengan cara ini, yang dapat menyebabkan masalah jika kode yang dieksekusi bukan bagian dari grafik ini, misalnya kode yang dipanggil oleh refleksi. Dengan menulis aturan keep Anda sendiri, Anda dapat memberi tahu R8 kode yang perlu tetap ada di aplikasi.

Untuk menambahkan aturan keep, tambahkan baris -keep dalam file proguard-rules.pro.

Mempertahankan sintaksis aturan

Aturan Keep umumnya mengikuti format ini:

-<KeepOption> [OptionalModifier,...] <ClassSpecification> [{ OptionalMemberSpecification }]

Misalnya, untuk mempertahankan class tertentu dan semua anggotanya, gunakan kode berikut:

-keep class com.myapp.MyClass { *; }

Untuk contoh lainnya, lihat bagian contoh.

Berikut adalah fungsi komponen aturan keep:

  • <KeepOption> memungkinkan Anda menentukan aspek class yang akan dipertahankan:

    Opsi Keep Deskripsi

    -keep

    Pertahankan class dan anggota yang tercantum dalam [{ OptionalMemberSpecification }].

    -keepclassmembers

    Mengizinkan pengoptimalan class; jika class dipertahankan, pertahankan anggota yang tercantum dalam [{ OptionalMemberSpecification }].

    -keepnames

    Izinkan penghapusan class dan anggota, tetapi jangan melakukan obfuscation atau modifikasi dengan cara lain.

    -keepclassmembernames

    Izinkan penghapusan class dan anggota, tetapi jangan mengaburkan atau mengubah anggota dengan cara lain.

    -keepclasseswithmembers

    Tidak ada penghapusan atau obfuscation class jika anggota cocok dengan pola yang ditentukan.

    Sebaiknya gunakan -keepclassmembers, karena fitur ini mengaktifkan pengoptimalan terbanyak, lalu -keepnames jika diperlukan. -keep tidak mengizinkan pengoptimalan apa pun, jadi coba gunakan seperlunya.

  • [OptionalModifier],...] memungkinkan Anda mencantumkan nol atau beberapa pengubah bahasa Java dari class, misalnya public atau final.

  • <ClassSpecification> memungkinkan Anda menentukan class mana (atau superclass atau antarmuka yang diimplementasikan) yang akan diterapkan aturan keep. Dalam kasus yang paling sederhana, ini adalah satu class yang sepenuhnya memenuhi syarat.

  • [{ OptionalMemberSpecification }] memungkinkan Anda memfilter perilaku keep hanya untuk class dan metode yang cocok dengan pola tertentu. Umumnya, hal ini direkomendasikan di sebagian besar aturan keep untuk mencegah penyimpanan lebih dari yang diinginkan.

Contoh aturan Keep

Berikut adalah beberapa contoh aturan simpan yang dirancang dengan baik.

Membuat subclass

Aturan keep ini dikemas di dalam androidx.room:room-runtime untuk membuat konstruktor database dibuat instance-nya oleh refleksi.

-keep class * extends androidx.room.RoomDatabase { void <init>(); }

Refleksi dari Android Framework ObjectAnimator

Aturan keep ini dikemas di dalam androidx.vectordrawable:vectordrawable-animated untuk memungkinkan ObjectAnimator memanggil pengambil atau penyetel dari kode native dengan JNI. Perhatikan bahwa sistem animasi yang lebih baru di Compose tidak memerlukan aturan keep seperti ini, ini hanyalah contoh struktur aturan.

-keepclassmembers class androidx.vectordrawable.graphics.drawable.VectorDrawableCompat$* {
   void set*(***);
   *** get*();
}

Pendaftaran JNI

Aturan keep ini dikemas di dalam androidx.graphics:graphics-path, yang digunakan untuk menyimpan metode native. Hal ini mungkin diperlukan jika library Anda mendaftarkan metode native secara manual dengan env->RegisterNatives().

-keepclasseswithmembers class androidx.graphics.path.** {
    native <methods>;
}