Sdílet prostřednictvím


ProGuard

Xamarin.Android ProGuard je zmenšovač tříd Java, optimalizátor a předběžné ověření. Zjistí a odebere nepoužívaný kód, analyzuje a optimalizuje bajtové kódy. Tato příručka vysvětluje, jak Funguje ProGuard, jak ho povolit v projektu a jak ho nakonfigurovat. Poskytuje také několik příkladů konfigurací ProGuard.

Přehled

ProGuard zjistí a odebere nepoužívané třídy, pole, metody a atributy z zabalené aplikace. To může dokonce udělat totéž pro odkazované knihovny (to vám může pomoct vyhnout se limitu 64 tisíc odkazů). Nástroj ProGuard ze sady Android SDK také optimalizuje bajtové kódy a odebere nepoužívané pokyny k kódu. ProGuard přečte vstupní soubory JAR a pak je zmenší, optimalizuje a předem ověří, zapíše výsledky do jednoho nebo více výstupních souborů JAR.

ProGuard zpracovává vstupní soubor APK pomocí následujících kroků:

  1. Zmenšovací krok – ProGuard rekurzivně určuje, které třídy a členy třídy se používají. Všechny ostatní třídy a členy třídy se zahodí.

  2. Krok optimalizace – ProGuard dále optimalizuje kód. Mimo jiné optimalizace, třídy a metody, které nejsou vstupní body mohou být privátní, statické nebo konečné, nepoužité parametry lze odebrat a některé metody mohou být vloženy.

  3. Krok obfuskace – V nativním vývoji pro Android přejmenuje ProGuard třídy a členy třídy, které nejsou vstupními body. Zachování vstupních bodů zajistí, že k nim budou mít přístup jejich původní názvy. Tento krok ale Xamarin.Android nepodporuje, protože aplikace je zkompilovaná do jazyka IL (Intermediate Language).

  4. Krok předběžného ověření – provádí kontroly v bajtech Java před modulem runtime a opatřuje poznámkami soubory tříd pro výhodu virtuálního počítače v Javě. Toto je jediný krok, který nemusí znát vstupní body.

Každý z těchto kroků je volitelný. Jak je vysvětleno v další části, Xamarin.Android ProGuard používá pouze podmnožinu těchto kroků.

ProGuard v Xamarin.Androidu

Konfigurace Xamarin.Android ProGuard neobfuscate APK. Ve skutečnosti není možné povolit obfuskace prostřednictvím ProGuard (i prostřednictvím použití vlastních konfiguračních souborů). Proto Xamarin.Android ProGuard provádí pouze kroky zmenšení a optimalizace :

Shrinking and optimization steps

Jednou z důležitých položek, které je potřeba vědět předem před použitím Nástroje ProGuard, je to, jak funguje v rámci Xamarin.Android procesu sestavení. Tento proces používá dva samostatné kroky:

  1. Xamarin Android Linker

  2. ProGuard

Každý z těchto kroků je popsán dále.

Krok linkeru

Linker Xamarin.Android využívá statickou analýzu vaší aplikace k určení následujících možností:

  • Která sestavení se ve skutečnosti používají.

  • Které typy se skutečně používají.

  • Které členy se skutečně používají.

Linker se vždy spustí před krokem ProGuard. Z tohoto důvodu může linker izolovat sestavení, typ nebo člen, na které byste mohli očekávat, že Bude spuštěn ProGuard. (Další informace o propojení v Xamarin.Androidu najdete v tématu Propojení v Androidu.)

Krok ProGuard

Po úspěšném dokončení kroku linkeru se spustí Nástroj ProGuard, který odebere nepoužívané bajtové kódování Java. Toto je krok, který optimalizuje APK.

Použití Nástroje ProGuard

Pokud chcete v projektu aplikace použít ProGuard, musíte nejdřív povolit ProGuard. Dále můžete buď nechat proces sestavení Xamarin.Android použít výchozí konfigurační soubor ProGuard, nebo můžete vytvořit vlastní konfigurační soubor pro ProGuard, který bude používat.

Povolení ProGuardu

Pomocí následujících kroků povolte v projektu aplikace Nástroj ProGuard:

  1. Ujistěte se, že je projekt nastavený na konfiguraci vydané verze (to je důležité, protože linker musí běžet, aby mohl ProGuard běžet):

    Select Release configuration

  2. V rozevíracím seznamu ProGuard kódu v okně Možnosti androidu vlastnosti > zvolte ProGuard:

    Proguard code shrinker selected

U většiny aplikací Xamarin.Android bude výchozí konfigurační soubor ProGuard, který poskytuje Xamarin.Android, dostačující k odebrání všech (a pouze) nepoužívaných kódů. Pokud chcete zobrazit výchozí konfiguraci ProGuard, otevřete soubor na adrese obj\Release\proguard\proguard_xamarin.cfg.

Následující příklad ukazuje typický vygenerovaný soubor proguard_xamarin.cfg :

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

Další část popisuje, jak vytvořit přizpůsobený konfigurační soubor ProGuard.

Přizpůsobení ProGuardu

Volitelně můžete přidat vlastní konfigurační soubor ProGuard, který bude mít větší kontrolu nad nástroji ProGuard. Můžete například explicitně říct ProGuard, které třídy mají být zachovány. Uděláte to tak, že vytvoříte nový soubor .cfg a použijete ProGuardConfiguration akci sestavení v podokně Vlastnosti Průzkumník řešení:

ProguardConfiguration build action selected

Mějte na paměti, že tento konfigurační soubor nenahrazuje soubor Xamarin.Android proguard_xamarin.cfg , protože oba soubory používají ProGuard.

Mohou existovat případy, kdy ProGuard nemůže správně analyzovat vaši aplikaci; může potenciálně odebrat kód, který vaše aplikace skutečně potřebuje. V takovém případě můžete přidat řádek do vlastního konfiguračního -keep souboru ProGuard:

-keep public class MyClass

V tomto příkladu MyClass je nastaven na skutečný název třídy, kterou chcete ProGuard přeskočit.

Vlastní jména můžete také zaregistrovat v [Register] poznámkách a použít je k přizpůsobení pravidel ProGuard. Názvy adaptérů, zobrazení, broadcastReceivers, Services, ContentProviders, Activities a Fragments můžete zaregistrovat. Další informace o použití vlastního atributu [Register] naleznete v tématu Práce s JNI.

Možnosti ProGuardu

ProGuard nabízí řadu možností, které můžete nakonfigurovat tak, aby poskytovaly podrobnější kontrolu nad jeho operací. Příručka ProGuard poskytuje kompletní referenční dokumentaci pro použití ProGuard.

Xamarin.Android podporuje následující možnosti ProGuard:

Xamarin.Android ignoruje následující možnosti:

ProGuard a Android Nougat

Pokud se pokoušíte použít ProGuard pro Android 7.0 nebo novější, musíte stáhnout novější verzi ProGuard, protože sada Android SDK nedoručí novou verzi, která je kompatibilní s JDK 1.8.

Tento balíček NuGet můžete použít k instalaci novější verze proguard.jar. Další informace o aktualizaci výchozí sady Android SDK proguard.jarnajdete v této diskuzi o Stack Overflow .

Všechny verze ProGuard najdete na stránce SourceForge.

Příklady konfigurací ProGuard

Níže jsou uvedeny dva příklady konfiguračních souborů ProGuard. Upozorňujeme, že v těchto případech proces sestavení Xamarin.Android poskytne vstupní, výstupní a knihovnové soubory JAR. Proto se můžete zaměřit na další možnosti, jako -keepje .

Jednoduchá aktivita Androidu

Následující příklad znázorňuje konfiguraci jednoduché aktivity Androidu:

-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

Úplná aplikace pro Android

Následující příklad znázorňuje konfiguraci kompletní aplikace pro Android:

-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 a proces sestavení Xamarin.Android

Následující části vysvětlují, jak ProGuard běží během sestavení verze Xamarin.Android.

Jaký příkaz je spuštěný ProGuard?

ProGuard je jednoduše .jar poskytována se sadou Android SDK. Proto se vyvolá v příkazu:

java -jar proguard.jar options ...

Úloha ProGuard

Úloha ProGuard se nachází uvnitř sestavení Xamarin.Android.Build.Tasks.dll . Je součástí _CompileToDalvikWithDx cíle, což je část _CompileDex cíle.

Následující výpis obsahuje příklad výchozích parametrů, které se vygenerují po vytvoření nového projektu pomocí nového projektu 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

Následující příklad znázorňuje typický příkaz ProGuard, který se spouští z integrovaného vývojového prostředí (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

Řešení problému

Problémy se soubory

Následující chybová zpráva může být zobrazena, když ProGuard přečte jeho konfigurační soubor:

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

K tomuto problému obvykle dochází ve Windows, protože .cfg soubor má nesprávné kódování. ProGuard nemůže zpracovat značku pořadí bajtů (BOM), která může být v textových souborech. Pokud je k dispozici kusovník, ProGuard se ukončí s výše uvedenou chybou.

Chcete-li zabránit tomuto problému, upravte vlastní konfigurační soubor z textového editoru, který umožní uložení souboru bez kusovníku. Chcete-li tento problém vyřešit, ujistěte se, že váš textový editor má jeho kódování nastaveno na UTF-8. Například textový editor Poznámkový blok++ může při ukládání souboru ukládat soubory bez kusovníku tak, že při ukládání souboru vybere kódování kódování > v kódování UTF-8 bez kusovníku.

Další problémy

Stránka Řešení potíží s ProGuardem popisuje běžné problémy, se kterými se můžete setkat (a jejich řešení) při používání nástroje ProGuard.

Shrnutí

Tento průvodce vysvětluje, jak Funguje ProGuard v Xamarin.Androidu, jak ho povolit v projektu aplikace a jak ho nakonfigurovat. Poskytuje ukázkové konfigurace ProGuard a popisuje řešení běžných problémů. Další informace o nástroji ProGuard a Androidu naleznete v tématu Zmenšení kódu a prostředků.