Aracılığıyla paylaş


ProGuard

Xamarin.Android ProGuard bir Java sınıf dosya küçültücü, iyileştirici ve ön doğrulayıcıdır. Kullanılmayan kodu algılar ve kaldırır, bayt kodunu analiz eder ve iyileştirir. Bu kılavuzda ProGuard'ın nasıl çalıştığı, projenizde nasıl etkinleştirileceği ve nasıl yapılandırileceği açıklanmaktadır. Ayrıca ProGuard yapılandırmalarının birkaç örneğini de sağlar.

Genel bakış

ProGuard kullanılmayan sınıfları, alanları, yöntemleri ve öznitelikleri paketlenmiş uygulamanızdan algılar ve kaldırır. Başvuruda bulunan kitaplıklar için de aynısını yapabilir (bu, 64k başvuru sınırından kaçınmanıza yardımcı olabilir). Android SDK'sının ProGuard aracı da bayt kodunu iyileştirir ve kullanılmayan kod yönergelerini kaldırır. ProGuard giriş jar'larını okur ve ardından daraltır, iyileştirir ve önceden doğrular; sonuçları bir veya daha fazla çıkış jar'sına yazar.

ProGuard, aşağıdaki adımları kullanarak apk girişlerini işler:

  1. Küçültme adımı – ProGuard hangi sınıfların ve sınıf üyelerinin kullanıldığını yinelemeli olarak belirler. Diğer tüm sınıflar ve sınıf üyeleri atılır.

  2. İyileştirme adımı – ProGuard kodu daha da iyileştirir. Diğer iyileştirmelerin yanı sıra, giriş noktası olmayan sınıflar ve yöntemler özel, statik veya son yapılabilir, kullanılmayan parametreler kaldırılabilir ve bazı yöntemler çizili olabilir.

  3. Gizleme adımı – Yerel Android geliştirmesinde ProGuard, giriş noktası olmayan sınıfları ve sınıf üyelerini yeniden adlandırır. Giriş noktalarının korunması, bunlara özgün adlarıyla erişmeye devam edilebilmesini sağlar. Ancak, uygulama Ara Dil'e (IL) kadar derlendiğinden bu adım Xamarin.Android tarafından desteklenmez.

  4. Doğrulama adımı – Java bayt kodları üzerinde çalışma zamanından önce denetimler gerçekleştirir ve Java VM'sinin yararına sınıf dosyalarına ek açıklama ekler. Bu, giriş noktalarını bilmesi gerekmeyen tek adımdır.

Bu adımların her biri isteğe bağlıdır. Sonraki bölümde açıklandığı gibi, Xamarin.Android ProGuard bu adımların yalnızca bir alt kümesini kullanır.

Xamarin.Android'de ProGuard

Xamarin.Android ProGuard yapılandırması APK'yi karartmıyor. Aslında, ProGuard aracılığıyla (özel yapılandırma dosyalarının kullanımı aracılığıyla bile) gizlemeyi etkinleştirmek mümkün değildir. Bu nedenle, Xamarin.Android'in ProGuard'ı yalnızca küçültme ve iyileştirme adımlarını gerçekleştirir:

Shrinking and optimization steps

ProGuard'ı kullanmadan önce önceden bilmeniz gereken önemli bir öğe, derleme işlemi içinde Xamarin.Android nasıl çalıştığıdır. Bu işlem iki ayrı adım kullanır:

  1. Xamarin Android Bağlayıcısı

  2. ProGuard

Bu adımların her biri bundan sonra açıklanmıştır.

Bağlayıcı Adımı

Xamarin.Android bağlayıcısı, aşağıdakileri belirlemek için uygulamanızın statik analizini çalıştırır:

  • Hangi derlemeler aslında kullanılır.

  • Gerçekte hangi türlerin kullanıldığı.

  • Hangi üyeler aslında kullanılır.

Bağlayıcı her zaman ProGuard adımından önce çalışır. Bu nedenle bağlayıcı, ProGuard'ın üzerinde çalışmasını bekleyebileceğiniz bir derlemeyi/türü/üyeyi soyabilir. (Xamarin.Android'de bağlama hakkında daha fazla bilgi için bkz. Android'de bağlama.)

ProGuard Adımı

Bağlayıcı adımı başarıyla tamamlandıktan sonra, kullanılmayan Java bayt kodunu kaldırmak için ProGuard çalıştırılır. Bu, APK'yi en iyi duruma getiren adımdır.

ProGuard kullanma

Uygulama projenizde ProGuard'ı kullanmak için önce ProGuard'ı etkinleştirmeniz gerekir. Ardından, Xamarin.Android derleme işleminin varsayılan bir ProGuard yapılandırma dosyası kullanmasına izin verebilir veya ProGuard'ın kullanması için kendi özel yapılandırma dosyanızı oluşturabilirsiniz.

ProGuard'ın etkinleştirilmesi

Uygulama projenizde ProGuard'ı etkinleştirmek için aşağıdaki adımları kullanın:

  1. Projenizin Yayın yapılandırmasına ayarlandığından emin olun (bağlayıcının ProGuard'ın çalışması için çalışması gerektiğinden bu önemlidir):

    Select Release configuration

  2. Özellikler Android Seçenekleri penceresindeki Kod daraltıcı açılan listesinden ProGuard'ı seçin: >

    Proguard code shrinker selected

Çoğu Xamarin.Android uygulaması için, Xamarin.Android tarafından sağlanan varsayılan ProGuard yapılandırma dosyası kullanılmayan kodun tümünü (ve yalnızca) kaldırmak için yeterli olacaktır. Varsayılan ProGuard yapılandırmasını görüntülemek için obj\Release\proguard\proguard_xamarin.cfg konumunda dosyayı açın.

Aşağıdaki örnek, tipik bir oluşturulan proguard_xamarin.cfg dosyasını gösterir:

# 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);
}

Sonraki bölümde özelleştirilmiş bir ProGuard yapılandırma dosyasının nasıl oluşturulacağı açıklanmaktadır.

ProGuard'ın Özelleştirilmesi

İsteğe bağlı olarak, ProGuard araçları üzerinde daha fazla denetim sağlamak için özel bir ProGuard Yapılandırma dosyası ekleyebilirsiniz. Örneğin, ProGuard'a hangi sınıfların tutulabileceğini açıkça söylemek isteyebilirsiniz. Bunu yapmak için yeni bir .cfg dosyası oluşturun ve Çözüm Gezgini Özellikler bölmesinde derleme eylemini uygulayınProGuardConfiguration:

ProguardConfiguration build action selected

Her ikisi de ProGuard tarafından kullanıldığından bu yapılandırma dosyasının Xamarin.Android proguard_xamarin.cfg dosyasının yerini almadığını unutmayın.

ProGuard'ın uygulamanızı düzgün bir şekilde analiz edemediği durumlar olabilir; uygulamanızın gerçekten ihtiyaç duyduğu kodu kaldırabilir. Böyle bir durumda, özel ProGuard yapılandırma dosyanıza bir -keep satır ekleyebilirsiniz:

-keep public class MyClass

Bu örnekte, MyClass ProGuard'ın atlanmasını istediğiniz sınıfın gerçek adına ayarlanır.

Ayrıca, ek açıklamalarla [Register] kendi adlarınızı kaydedebilir ve ProGuard kurallarını özelleştirmek için bu adları kullanabilirsiniz. Bağdaştırıcılar, Görünümler, BroadcastReceivers, Hizmetler, ContentProviders, Etkinlikler ve Parçalar için adları kaydedebilirsiniz. Özel özniteliği kullanma [Register] hakkında daha fazla bilgi için bkz . JNI ile çalışma.

ProGuard Seçenekleri

ProGuard, işlemi üzerinde daha hassas denetim sağlamak için yapılandırabileceğiniz bir dizi seçenek sunar. ProGuard Kılavuzu, ProGuard kullanımı için eksiksiz başvuru belgeleri sağlar.

Xamarin.Android aşağıdaki ProGuard seçeneklerini destekler:

Aşağıdaki seçenekler Xamarin.Android tarafından yoksayılır :

ProGuard ve Android Nougat

ProGuard'ı Android 7.0 veya üzeri sürümlerde kullanmaya çalışıyorsanız, Android SDK'sı JDK 1.8 ile uyumlu yeni bir sürüm göndermediğinden ProGuard'ın daha yeni bir sürümünü indirmeniz gerekir.

Daha yeni bir sürümünü proguard.jaryüklemek için bu NuGet paketini kullanabilirsiniz. Varsayılan Android SDK'sını proguard.jargüncelleştirme hakkında daha fazla bilgi için bu Stack Overflow tartışmasını inceleyin.

ProGuard'ın tüm sürümlerini SourceForge sayfasında bulabilirsiniz.

Örnek ProGuard Yapılandırmaları

Aşağıda iki örnek ProGuard yapılandırma dosyası listelenmiştir. Bu gibi durumlarda Xamarin.Android derleme işleminin giriş, çıkış ve kitaplık jar'larını sağladığını lütfen unutmayın. Böylece gibi -keepdiğer seçeneklere odaklanabilirsiniz.

Basit bir Android etkinliği

Aşağıdaki örnekte basit bir Android etkinliğinin yapılandırması gösterilmektedir:

-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

Eksiksiz bir Android uygulaması

Aşağıdaki örnekte eksiksiz bir Android uygulamasının yapılandırması gösterilmektedir:

-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 ve Xamarin.Android Derleme İşlemi

Aşağıdaki bölümlerde ProGuard'ın bir Xamarin.Android Sürümü derlemesi sırasında nasıl çalıştığı açıklanmaktadır.

ProGuard hangi komutu çalıştırıyor?

ProGuard, Android SDK ile sağlanan bir .jar özelliktir. Bu nedenle, bir komutta çağrılır:

java -jar proguard.jar options ...

ProGuard Görevi

ProGuard görevi Xamarin.Android.Build.Tasks.dll derlemesinde bulunur. Hedefin _CompileToDalvikWithDx bir parçası olan hedefin _CompileDex bir parçasıdır.

Aşağıdaki liste, Dosya > Yeni Projesi'ni kullanarak yeni bir proje oluşturduktan sonra oluşturulan varsayılan parametrelerin bir örneğini sağlar:

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

Sonraki örnekte IDE'den çalıştırılacak tipik bir ProGuard komutu gösterilmektedir:

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

Sorun giderme

Dosya Sorunları

ProGuard yapılandırma dosyasını okuduğunda aşağıdaki hata iletisi görüntülenebilir:

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

Dosya yanlış kodlamaya .cfg sahip olduğundan bu sorun genellikle Windows'ta oluşur. ProGuard, metin dosyalarında bulunabilecek bayt sipariş işaretini (BOM) işleyemiyor. Ürün reçetesi varsa, ProGuard yukarıdaki hatayla birlikte çıkar.

Bu sorunu önlemek için, dosyanın ürün reçetesi olmadan kaydedilmesini sağlayacak bir metin düzenleyicisinden özel yapılandırma dosyasını düzenleyin. Bu sorunu çözmek için metin düzenleyicinizin kodlaması olarak UTF-8ayarlandığından emin olun. Örneğin, Not Defteri++ metin düzenleyicisi dosyayı kaydederken UTF-8 Ürün Reçetesi Olmadan Kodlama'yı > seçerek bom olmadan dosyaları kaydedebilir.

Diğer Sorunlar

ProGuard Sorun Giderme sayfası, ProGuard kullanırken karşılaşabileceğiniz yaygın sorunları (ve çözümleri) açıklar.

Özet

Bu kılavuzda ProGuard'ın Xamarin.Android'de nasıl çalıştığı, uygulama projenizde nasıl etkinleştirileceği ve nasıl yapılandırileceği açıklanmıştır. Örnek ProGuard yapılandırmaları sağladı ve yaygın sorunların çözümlerini anlattı. ProGuard aracı ve Android hakkında daha fazla bilgi için bkz . Kodunuzu ve Kaynaklarınızı Küçültme.