Bagikan melalui


ProGuard

Xamarin.Android ProGuard adalah shrinker, pengoptimal, dan pra-verifikasi file kelas Java. Ini mendeteksi dan menghapus kode yang tidak digunakan, menganalisis dan mengoptimalkan bytecode. Panduan ini menjelaskan cara kerja ProGuard, cara mengaktifkannya di proyek Anda, dan cara mengonfigurasinya. Ini juga menyediakan beberapa contoh konfigurasi ProGuard.

Gambaran Umum

ProGuard mendeteksi dan menghapus kelas, bidang, metode, dan atribut yang tidak digunakan dari aplikasi paket Anda. Ini bahkan dapat melakukan hal yang sama untuk pustaka yang direferensikan (ini dapat membantu Anda menghindari batas referensi 64k). Alat ProGuard dari Android SDK juga akan mengoptimalkan bytecode dan menghapus instruksi kode yang tidak digunakan. ProGuard membaca jar input dan kemudian menyusutkan, mengoptimalkan, dan memverifikasinya sebelumnya; ia menulis hasilnya ke satu atau beberapa jar output.

ProGuard memproses APK input menggunakan langkah-langkah berikut:

  1. Langkah penyusutan – ProGuard secara rekursif menentukan kelas dan anggota kelas mana yang digunakan. Semua kelas dan anggota kelas lainnya dibuang.

  2. Langkah pengoptimalan - ProGuard lebih mengoptimalkan kode. Di antara pengoptimalan lainnya, kelas dan metode yang bukan titik masuk dapat dibuat parameter privat, statis, atau final, yang tidak digunakan dapat dihapus, dan beberapa metode mungkin di-inlin.

  3. Langkah obfuscation – Dalam pengembangan Android asli, ProGuard mengganti nama kelas dan anggota kelas yang bukan titik masuk. Mempertahankan titik masuk memastikan bahwa mereka masih dapat diakses dengan nama aslinya. Namun, langkah ini tidak didukung oleh Xamarin.Android karena aplikasi dikompilasi ke Bahasa Perantara (IL).

  4. Langkah preverifikasi – Melakukan pemeriksaan pada bytecode Java sebelum runtime dan membuat anotasi file kelas untuk keuntungan Java VM. Ini adalah satu-satunya langkah yang tidak perlu mengetahui titik masuk.

Masing-masing langkah ini bersifat opsional. Seperti yang akan dijelaskan di bagian berikutnya, Xamarin.Android ProGuard hanya menggunakan subset langkah-langkah ini.

ProGuard di Xamarin.Android

Konfigurasi Xamarin.Android ProGuard tidak mengaburkan APK. Bahkan, tidak mungkin untuk mengaktifkan obfuscation melalui ProGuard (bahkan melalui penggunaan file konfigurasi kustom). Dengan demikian, ProGuard Xamarin.Android hanya melakukan langkah-langkah penyusutan dan pengoptimalan:

Shrinking and optimization steps

Salah satu item penting yang perlu diketahui sebelumnya sebelum menggunakan ProGuard adalah cara kerjanya dalam Xamarin.Android proses build. Proses ini menggunakan dua langkah terpisah:

  1. Xamarin Android Linker

  2. ProGuard

Masing-masing langkah ini dijelaskan berikutnya.

Langkah Linker

Linker Xamarin.Android menggunakan analisis statis aplikasi Anda untuk menentukan hal berikut:

  • Rakitan mana yang benar-benar digunakan.

  • Jenis mana yang benar-benar digunakan.

  • Anggota mana yang benar-benar digunakan.

Linker akan selalu berjalan sebelum langkah ProGuard. Karena itu, linker dapat menghapus rakitan/jenis/anggota yang mungkin Anda harapkan agar ProGuard berjalan. (Untuk informasi selengkapnya tentang menautkan di Xamarin.Android, lihat Menautkan di Android.)

Langkah ProGuard

Setelah langkah linker berhasil diselesaikan, ProGuard dijalankan untuk menghapus bytecode Java yang tidak digunakan. Ini adalah langkah yang mengoptimalkan APK.

Menggunakan ProGuard

Untuk menggunakan ProGuard di proyek aplikasi, Anda harus terlebih dahulu mengaktifkan ProGuard. Selanjutnya, Anda dapat membiarkan proses build Xamarin.Android menggunakan file konfigurasi ProGuard default, atau Anda dapat membuat file konfigurasi kustom Anda sendiri untuk digunakan ProGuard.

Mengaktifkan ProGuard

Gunakan langkah-langkah berikut untuk mengaktifkan ProGuard di proyek aplikasi Anda:

  1. Pastikan proyek Anda diatur ke konfigurasi Rilis (ini penting karena linker harus berjalan agar ProGuard dapat berjalan):

    Select Release configuration

  2. Pilih ProGuard dari daftar drop-down Code shrinker di jendela Opsi Android Properti>:

    Proguard code shrinker selected

Untuk sebagian besar aplikasi Xamarin.Android, file konfigurasi ProGuard default yang disediakan oleh Xamarin.Android akan cukup untuk menghapus semua (dan hanya) kode yang tidak digunakan. Untuk melihat konfigurasi ProGuard default, buka file di obj\Release\proguard\proguard_xamarin.cfg.

Contoh berikut mengilustrasikan file proguard_xamarin.cfg yang dihasilkan secara umum:

# This is Xamarin-specific (and enhanced) configuration.

-dontobfuscate

-keep class mono.MonoRuntimeProvider { *; <init>(...); }
-keep class mono.MonoPackageManager { *; <init>(...); }
-keep class mono.MonoPackageManager_Resources { *; <init>(...); }
-keep class mono.android.** { *; <init>(...); }
-keep class mono.java.** { *; <init>(...); }
-keep class mono.javax.** { *; <init>(...); }
-keep class opentk.platform.android.AndroidGameView { *; <init>(...); }
-keep class opentk.GameViewBase { *; <init>(...); }
-keep class opentk_1_0.platform.android.AndroidGameView { *; <init>(...); }
-keep class opentk_1_0.GameViewBase { *; <init>(...); }

-keep class android.runtime.** { <init>(***); }
-keep class assembly_mono_android.android.runtime.** { <init>(***); }
# hash for android.runtime and assembly_mono_android.android.runtime.
-keep class md52ce486a14f4bcd95899665e9d932190b.** { *; <init>(...); }
-keepclassmembers class md52ce486a14f4bcd95899665e9d932190b.** { *; <init>(...); }

# Android's template misses fluent setters...
-keepclassmembers class * extends android.view.View {
   *** set*(***);
}

# also misses those inflated custom layout stuff from xml...
-keepclassmembers class * extends android.view.View {
   <init>(android.content.Context,android.util.AttributeSet);
   <init>(android.content.Context,android.util.AttributeSet,int);
}

Bagian berikutnya menjelaskan cara membuat file konfigurasi ProGuard yang disesuaikan.

Menyesuaikan ProGuard

Secara opsional, Anda dapat menambahkan file Konfigurasi ProGuard kustom untuk mengerahkan lebih banyak kontrol atas alat ProGuard. Misalnya, Anda mungkin ingin secara eksplisit memberi tahu ProGuard kelas mana yang harus disimpan. Untuk melakukan ini, buat file .cfg baru dan terapkan ProGuardConfiguration tindakan build di panel Properti Penjelajah Solusi:

ProguardConfiguration build action selected

Perlu diingat bahwa file konfigurasi ini tidak menggantikan file Xamarin.Android proguard_xamarin.cfg karena keduanya digunakan oleh ProGuard.

Mungkin ada kasus di mana ProGuard tidak dapat menganalisis aplikasi Anda dengan benar; itu berpotensi menghapus kode yang sebenarnya dibutuhkan aplikasi Anda. Jika ini terjadi, Anda dapat menambahkan -keep baris ke file konfigurasi ProGuard kustom Anda:

-keep public class MyClass

Dalam contoh ini, MyClass diatur ke nama aktual kelas yang Anda inginkan untuk dilewati ProGuard.

Anda juga dapat mendaftarkan nama Anda sendiri dengan [Register] anotasi dan menggunakan nama-nama ini untuk menyesuaikan aturan ProGuard. Anda dapat mendaftarkan nama untuk Adaptor, Tampilan, BroadcastReceivers, Layanan, ContentProviders, Aktivitas, dan Fragmen. Untuk informasi selengkapnya tentang menggunakan [Register] atribut kustom, lihat Bekerja dengan JNI.

Opsi ProGuard

ProGuard menawarkan sejumlah opsi yang dapat Anda konfigurasi untuk memberikan kontrol yang lebih baik atas operasinya. ProGuard Manual menyediakan dokumentasi referensi lengkap untuk penggunaan ProGuard.

Xamarin.Android mendukung opsi ProGuard berikut:

Opsi berikut diabaikan oleh Xamarin.Android:

ProGuard dan Android Nougat

Jika Anda mencoba menggunakan ProGuard terhadap Android 7.0 atau yang lebih baru, Anda harus mengunduh versi ProGuard yang lebih baru karena Android SDK tidak mengirimkan versi baru yang kompatibel dengan JDK 1.8.

Anda dapat menggunakan paket NuGet ini untuk menginstal versi yang lebih baru dari proguard.jar. Untuk informasi selengkapnya tentang memperbarui Android SDK proguard.jardefault, lihat diskusi Stack Overflow ini.

Anda dapat menemukan semua versi ProGuard di halaman SourceForge.

Contoh Konfigurasi ProGuard

Dua contoh file konfigurasi ProGuard tercantum di bawah ini. Harap dicatat bahwa, dalam kasus ini, proses build Xamarin.Android akan menyediakan input, output, dan jar pustaka. Dengan demikian, Anda dapat fokus pada opsi lain seperti -keep.

Aktivitas Android sederhana

Contoh berikut mengilustrasikan konfigurasi untuk aktivitas Android sederhana:

-injars  bin/classes
-outjars bin/classes-processed.jar
-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar

-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic

-keep public class mypackage.MyActivity

Aplikasi Android lengkap

Contoh berikut mengilustrasikan konfigurasi untuk aplikasi Android lengkap:

-injars  bin/classes
-injars  libs
-outjars bin/classes-processed.jar
-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar

-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
public static <fields>;
}

ProGuard dan Proses Build Xamarin.Android

Bagian berikut menjelaskan cara ProGuard berjalan selama build Rilis Xamarin.Android.

Perintah apa yang dijalankan ProGuard?

ProGuard hanya .jar disediakan dengan Android SDK. Dengan demikian, itu dipanggil dalam perintah:

java -jar proguard.jar options ...

Tugas ProGuard

Tugas ProGuard ditemukan di dalam rakitan Xamarin.Android.Build.Tasks.dll . Ini adalah bagian _CompileToDalvikWithDx dari target, yang merupakan bagian _CompileDex dari target.

Daftar berikut ini menyediakan contoh parameter default yang dihasilkan setelah Anda membuat proyek baru menggunakan File > New Project:

ProGuardJarPath = C:\Android\android-sdk\tools\proguard\lib\proguard.jar
AndroidSdkDirectory = C:\Android\android-sdk\
JavaToolPath = C:\Program Files (x86)\Java\jdk1.8.0_92\\bin
ProGuardToolPath = C:\Android\android-sdk\tools\proguard\
JavaPlatformJarPath = C:\Android\android-sdk\platforms\android-25\android.jar
ClassesOutputDirectory = obj\Release\android\bin\classes
AcwMapFile = obj\Release\acw-map.txt
ProGuardCommonXamarinConfiguration = obj\Release\proguard\proguard_xamarin.cfg
ProGuardGeneratedReferenceConfiguration = obj\Release\proguard\proguard_project_references.cfg
ProGuardGeneratedApplicationConfiguration = obj\Release\proguard\proguard_project_primary.cfg
ProGuardConfigurationFiles

    {sdk.dir}tools\proguard\proguard-android.txt;
    {intermediate.common.xamarin};
    {intermediate.references};
    {intermediate.application};
    ;

JavaLibrariesToEmbed = C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v7.0\mono.android.jar
ProGuardJarInput = obj\Release\proguard\__proguard_input__.jar
ProGuardJarOutput = obj\Release\proguard\__proguard_output__.jar
DumpOutput = obj\Release\proguard\dump.txt
PrintSeedsOutput = obj\Release\proguard\seeds.txt
PrintUsageOutput = obj\Release\proguard\usage.txt
PrintMappingOutput = obj\Release\proguard\mapping.txt

Contoh berikutnya mengilustrasikan perintah ProGuard khas yang dijalankan dari IDE:

C:\Program Files (x86)\Java\jdk1.8.0_92\\bin\java.exe -jar C:\Android\android-sdk\tools\proguard\lib\proguard.jar -include obj\Release\proguard\proguard_xamarin.cfg -include obj\Release\proguard\proguard_project_references.cfg -include obj\Release\proguard\proguard_project_primary.cfg "-injars 'obj\Release\proguard\__proguard_input__.jar';'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v7.0\mono.android.jar'" "-libraryjars 'C:\Android\android-sdk\platforms\android-25\android.jar'" -outjars "obj\Release\proguard\__proguard_output__.jar" -optimizations !code/allocation/variable

Pemecahan Masalah

Masalah File

Pesan kesalahan berikut dapat ditampilkan ketika ProGuard membaca file konfigurasinya:

Unknown option '-keep' in line 1 of file 'proguard.cfg'

Masalah ini biasanya terjadi pada Windows karena .cfg file memiliki pengodean yang salah. ProGuard tidak dapat menangani tanda urutan byte (BOM) yang mungkin ada dalam file teks. Jika BOM ada, Maka ProGuard akan keluar dengan kesalahan di atas.

Untuk mencegah masalah ini, edit file konfigurasi kustom dari editor teks yang akan memungkinkan file disimpan tanpa BOM. Untuk mengatasi masalah ini, pastikan editor teks Anda telah mengatur pengodeannya ke UTF-8. Misalnya, editor teks Notepad++ dapat menyimpan file tanpa BOM dengan memilih Encode Pengodean > di UTF-8 Tanpa BOM saat menyimpan file.

Masalah Lain

Halaman Pemecahan Masalah ProGuard membahas masalah umum yang mungkin Anda temui (dan solusi) saat menggunakan ProGuard.

Ringkasan

Panduan ini menjelaskan cara kerja ProGuard di Xamarin.Android, cara mengaktifkannya di proyek aplikasi Anda, dan cara mengonfigurasinya. Ini memberikan contoh konfigurasi ProGuard, dan menjelaskan solusi untuk masalah umum. Untuk informasi selengkapnya tentang alat ProGuard dan Android, lihat Menyusutkan Kode dan Sumber Daya Anda.