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:
Langkah penyusutan – ProGuard secara rekursif menentukan kelas dan anggota kelas mana yang digunakan. Semua kelas dan anggota kelas lainnya dibuang.
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.
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).
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:
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:
Xamarin Android Linker
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:
Pastikan proyek Anda diatur ke konfigurasi Rilis (ini penting karena linker harus berjalan agar ProGuard dapat berjalan):
Pilih ProGuard dari daftar drop-down Code shrinker di jendela Opsi Android Properti>:
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:
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.jar
default, 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.