Skip to content

Commit 06ebfe5

Browse files
committed
handler thread published and proguard added
1 parent 4953c4c commit 06ebfe5

File tree

6 files changed

+88
-2
lines changed

6 files changed

+88
-2
lines changed

_drafts/2019-09-16-gradle.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,13 @@ android {
111111
productFlavors {
112112
free {
113113
dimension "version"
114-
applicationId 'pl.androidcode.app.free'
114+
applicationIdSuffix ".free"
115+
versionNameSuffix "-free"
115116
}
116117
paid {
117118
dimension "version"
118-
applicationId 'pl.androidcode.app.paid'
119+
applicationIdSuffix ".paid"
120+
versionNameSuffix "-paid"
119121
}
120122
}
121123

_drafts/2019-09-23-proguard.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
layout: post
3+
title: "ProGuard"
4+
date: 2019-09-23
5+
categories: ["Budowanie"]
6+
image: build/proguard
7+
github: build/tree/master/proguard
8+
description: "Budowanie"
9+
keywords: "budowanie, kompilacja, konfiguracja, build, proguard, apk, properties, configuration, shrink, code, resource, keep, obfuscate, optimize, android, programowanie, programming"
10+
---
11+
12+
## 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.
14+
15+
## 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.
17+
18+
## Konfiguracja
19+
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.
20+
21+
{% highlight gradle %}
22+
android {
23+
24+
buildTypes {
25+
release {
26+
// Enable code shrinking, obfuscation, optimization
27+
minifyEnabled true
28+
29+
// Enable resource shrinking, requires minifyEnabled to be applied
30+
shrinkResources true
31+
32+
// Specify ProGuard rules files
33+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
34+
}
35+
debug {
36+
// don't need to enable minifyEnabled and shrinkResources for debug purpose
37+
}
38+
}
39+
40+
flavorDimensions "version"
41+
productFlavors {
42+
free {
43+
//...
44+
dimension "version"
45+
proguardFile 'free-rules.pro' //add extra rules for flavors
46+
}
47+
paid {
48+
//...
49+
dimension "version"
50+
}
51+
}
52+
}
53+
{% endhighlight %}
54+
55+
## 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`.
57+
58+
{% highlight pro %}
59+
-keep class CustomClass
60+
-keep class * implements CustomInterface
61+
-keep public class models.** { *; }
62+
{% endhighlight %}
63+
64+
## 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`.
66+
67+
{% highlight xml %}
68+
<resources
69+
xmlns:tools="http://schemas.android.com/tools"
70+
tools:keep="@layout/used1, @drawable/used2"
71+
tools:discard="@menu/unused1" />
72+
{% endhighlight %}
73+
74+
## 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`.
76+
77+
{% highlight pro %}
78+
-keepattributes SourceFile, LineNumberTable
79+
-keepattributes *Annotation*
80+
-keeppackagenames package.name
81+
{% endhighlight %}
82+
83+
## 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`.
File renamed without changes.
644 KB
Loading
20.6 KB
Loading
64.1 KB
Loading

0 commit comments

Comments
 (0)