Skip to content

Commit 95f61e0

Browse files
authored
proguard updated
1 parent 06ebfe5 commit 95f61e0

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

_drafts/2019-09-23-proguard.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ keywords: "budowanie, kompilacja, konfiguracja, build, proguard, apk, properties
1010
---
1111

1212
## Wstęp
13-
Podczas procesu budowania projektu warto zadbać o optymalizację rozmiaru pliku wyjściowego. W tym celu `Android Gradle plugin` wykorzystuje kompilator `R8` wraz z zasadami `ProGuard`. Pozwala on na zmniejszanie rozmiaru poprzez wycinanie nieużywanego kodu i zasobów oraz zaciemnianie kodu dodatkowo utrudniającego dekompilacje. Użycie kompilatora `R8` powinno być nieodłącznym elementem budowania wersji produkcyjnej.
13+
Podczas procesu budowania projektu warto zadbać o optymalizację rozmiaru pliku wyjściowego. W tym celu `Android Gradle plugin` wykorzystuje kompilator `R8` wraz z zasadami `ProGuard`. Pozwala on na zmniejszanie rozmiaru poprzez wycinanie nieużywanego kodu i zasobów oraz zaciemnianie kodu dodatkowo utrudniając dekompilacje. Użycie kompilatora `R8` powinno być nieodłącznym elementem budowania wersji produkcyjnej.
1414

1515
## Pliki
16-
Definiowanie zasad w plikach `ProGuard` pozwala na konfigurację i nadpisanie domyślnego zachowania kompilatora `R8`. `Android Studio` dla każdego modułu automatycznie tworzy pusty plik `proguard-rules.pro` w którym definiowane są zasady dla danego modułu natomiast `Android Gradle plugin` generuje `proguard-android-optimize.txt` zawierający zasady optymalizacji użyteczne dla projektów Android takie jak np. zachowanie adnotacji. Jeśli zewnętrzna biblioteka zawiera własne zasady `ProGuard` opisane w pliku `proguard.txt` i lokalizacji `META-INF/proguard` są one również addytywnie aplikowane dla całego projektu i nie mogą zostać usunięte co może w sposób niepożądany znacząco zmienić oczekiwaną konfiguracje. Ponadto po pozytywnym zakończeniu budowania projektu w podkatalogu wariantu budowania może zostać wygenerowany plik `aapt_rules.txt` zawierający zasady `keep` dla klas opisanych w manifeście, plikach layout i innych zasobach oznaczonych jako potencjalne punkty wejścia.
16+
Definiowanie zasad w plikach `ProGuard` pozwala na konfigurację i nadpisanie domyślnego zachowania kompilatora `R8`. `Android Studio` dla każdego modułu automatycznie tworzy pusty plik `proguard-rules.pro` w którym tworzone są zasady dla danego modułu natomiast `Android Gradle plugin` generuje `proguard-android-optimize.txt` zawierający zasady optymalizacji użyteczne dla projektów Android takie jak np. zachowanie adnotacji. Jeśli zewnętrzna biblioteka zawiera własne zasady `ProGuard` opisane w pliku `proguard.txt` i lokalizacji `META-INF/proguard` są one również addytywnie aplikowane dla całego projektu i nie mogą zostać usunięte co może w sposób niepożądany znacząco zmienić oczekiwaną konfiguracje. Ponadto po pozytywnym zakończeniu budowania projektu w podkatalogu wariantu budowania może zostać wygenerowany plik `aapt_rules.txt` zawierający zasady `keep` dla klas opisanych w manifeście, plikach layout i innych zasobach oznaczonych jako potencjalne punkty wejścia.
1717

1818
## Konfiguracja
1919
Podstawowa konfiguracja pliku `build.gradle` definuje zastosowanie lub pominięcie procesu zmniejszania, zaciemniania i optymalizacji zarówno dla kodu jak i zasobów za pomocą wpisów `minifyEnabled`, `shrinkResources` oraz `proguardFiles` dla ścieżki plików. Domyślnie są one jednak wyłączone ponieważ wydłużają czas kompilacji i mogą powodować występowanie błędów w przypadku niepełnej konfiguracji.
@@ -53,7 +53,7 @@ android {
5353
{% endhighlight %}
5454

5555
## Zmniejszanie kodu
56-
Zmniejszanie kodu (`code shrinking`) wykrywa i bezpiecznie usuwa nieużywane klasy, pola i metody z aplikacji oraz zewnętrznych zależności. W wyniku tego procesu plik `APK` zawiera tylko rzeczywiście używany kod co w niektórych sytuacjach może znacznie przyczynić się do redukcji rozmiaru. Cały proces jest jednak dość kosztowny i wydłuża czas kompilacji spowodowany analizą wszystkich `punktów wejścia` tzn. klas które mogą zostać użyte przez platformę do uruchomienia aktywności czy usługi. Na ich podstawie tworzony jest `graf` wszystkich metod, zmiennych i innych klas do których aplikacja może uzyskać dostęp w czasie działania. Kod niezawierający się w grafie jest traktowany jako nieosiągalny i może zostać usunięty z aplikacji. Przykładowo aplikacja wykorzystuje tylko kilka metod oraz klas z zewnętrznej biblioteki w związku z czym pozostała jej nieużywana przez aplikacje część może zostać zignorowana i niedołączona do plików `DEX`. Punkty wejścia są określane na podstawie automatycznie generowanego pliku `aapt_rules.txt` oraz ręcznie opisanych zasad `keep` w plikach `ProGuard`. Przeważnie `R8` usuwa tylko rzeczywiście nieużywany kod jednakże w przypadku użycia mechanizmu `refleksji` czy wywołań `JNI` (`Java Native Interface`) może nie być w stanie poprawnie zbudować grafu. W takim przypadku należy dodać odpowiednie zasady `keep` do pliku `ProGuard` lub oznaczyć fragmenty kodu adnotacją `@Keep`.
56+
Zmniejszanie kodu (`code shrinking`) wykrywa i bezpiecznie usuwa nieużywane klasy, pola i metody z aplikacji oraz zewnętrznych zależności. W wyniku tego procesu plik `APK` zawiera tylko rzeczywiście używany kod co w niektórych sytuacjach może znacznie przyczynić się do redukcji rozmiaru. Cały proces jest jednak dość kosztowny i wydłuża czas kompilacji spowodowany analizą wszystkich `punktów wejścia` tzn. klas które mogą zostać użyte przez platformę do uruchomienia aktywności czy usługi. Na ich podstawie tworzony jest `graf` wszystkich metod, zmiennych i innych klas do których aplikacja może uzyskać dostęp w czasie działania. Kod niezawierający się w grafie jest traktowany jako nieosiągalny i może zostać usunięty z aplikacji. Przykładowo aplikacja wykorzystuje tylko kilka metod oraz klas z zewnętrznej biblioteki w związku z czym pozostała jej nieużywana część może zostać zignorowana i niedołączona do plików `DEX`. Punkty wejścia określane są na podstawie automatycznie generowanego pliku `aapt_rules.txt` oraz ręcznie opisanych zasad `keep` w plikach `ProGuard`. Przeważnie `R8` usuwa tylko rzeczywiście nieużywany kod jednakże w przypadku użycia mechanizmu `refleksji` czy wywołań `JNI` (`Java Native Interface`) może nie być w stanie poprawnie zbudować grafu. W takim przypadku należy dodać odpowiednie zasady `keep` do pliku `proguard-rules.pro` lub oznaczyć fragmenty kodu adnotacją `@Keep`.
5757

5858
{% highlight pro %}
5959
-keep class CustomClass
@@ -62,7 +62,7 @@ Zmniejszanie kodu (`code shrinking`) wykrywa i bezpiecznie usuwa nieużywane kla
6262
{% endhighlight %}
6363

6464
## Zmniejszanie zasobów
65-
Podczas analizy dokonywanej przez kompilator poza budowaniem grafu oraz operacjami zmniejszania, zaciemniania i optymalizacji kodu następuje także identyfikacja i oznaczanie zasobów pod kątem wykorzystania w osiągalnym kodzie. Następnie w procesie zmniejszania zasobów (`resource shrinking`) te nieużywane zostają usunięte. Zasada ta nie dotyczy jednak zasobów alternatywnych np. inna gęstość czy język. Jeśli zasoby o tej samej nazwie, typie i kwalifikatorze występują w wielu lokalizacjach wówczas tylko jeden zostaje przekazany zgodnie z priorytetem (`build type > build flavor > main > library`). W przypadku budowania różnych wariantów aplikacji mogą występować różnice w rzeczywistym użyciu zasobów. W takiej sytuacji należy określić własne zasady zachowania zasobów definiowanych w pliku `xml` w folderze `raw`.
65+
Podczas analizy dokonywanej przez kompilator `R8` następuje także identyfikacja i oznaczanie zasobów pod kątem wykorzystania w osiągalnym kodzie. Następnie w procesie zmniejszania zasobów (`resource shrinking`) te nieużywane mogą zostać usunięte. Zasada ta nie dotyczy jednak zasobów alternatywnych np. inna gęstość czy język. Jeśli zasoby o tej samej nazwie, typie i kwalifikatorze występują w wielu lokalizacjach wówczas tylko jeden zostaje przekazany zgodnie z priorytetem (`build type > build flavor > main > library`). W przypadku budowania różnych wariantów aplikacji mogą występować różnice w rzeczywistym użyciu zasobów. W takiej sytuacji należy określić własne zasady zachowania zasobów definiowanych w pliku `xml` w folderze `raw`.
6666

6767
{% highlight xml %}
6868
<resources
@@ -72,13 +72,19 @@ Podczas analizy dokonywanej przez kompilator poza budowaniem grafu oraz operacja
7272
{% endhighlight %}
7373

7474
## Zaciemnianie
75-
Celem zaciemniania (`obfuscation`) kodu jest redukcja rozmiaru aplikacji oraz utrudnienie procesu dekompilacji. Realizowane jest to poprzez skrócenie nazw klas, metod i pól. Konfiguracja może być definiowana w zasadach `ProGuard`.
75+
Zaciemniania (`obfuscation`) jest częścią procesu zmniejszania kodu. Redukuje rozmiar aplikacji oraz utrudnienia dekompilację. Polega m.in. na skracaniu nazw klas, metod i pól.
7676

7777
{% highlight pro %}
78+
-renamesourcefileattribute SourceFile
7879
-keepattributes SourceFile, LineNumberTable
79-
-keepattributes *Annotation*
80-
-keeppackagenames package.name
80+
-keeppackagenames package.name.to.keep
8181
{% endhighlight %}
8282

8383
## Optymalizacja
84-
W trakcie procesu redukcji kodu kompilator `R8` dokonuje także analizy na głębszym poziomie w celu zastosowania optymalizacji. Jeśli kod nigdy nie osiągnie pewnego warunku wówczas cała przypisana mu gałąź może zostać usunięta. Ponadto kod może zostać także przepisany do krótszej formy, np. metoda wywoływana w jednym miejscu może zostać usunięta i jej ciało przeniesione w miejsce wywołania. Dodatkowe ustawienia optymalizacji deklarowane są w pliku `gradle.properties`.
84+
W trakcie procesu redukcji kodu kompilator `R8` dokonuje także analizy na głębszym poziomie w celu zastosowania optymalizacji. Jeśli kod nigdy nie osiągnie pewnego warunku wówczas cała przypisana mu gałąź może zostać usunięta. Ponadto kod może być także przepisany do krótszej formy, np. metoda wywoływana w jednym miejscu jest usunięta, a jej ciało przeniesione w miejsce wywołania. Domyślne ustawienia optymalizacji zawierają są w pliku `proguard-android-optimize.txt`.
85+
86+
{% highlight pro %}
87+
-optimizations !code/simplification/math
88+
-optimizationpasses 6
89+
-repackageclasses
90+
{% endhighlight %}

0 commit comments

Comments
 (0)