ProGuard — narzędzie do kompresji, optymalizacji i obfuskacji kodu bajtowego Java, zintegrowane z Android SDK do ochrony aplikacji przed reverse-engineering. Według Google I/O Security Session (2025), prawidłowa konfiguracja ProGuard zmniejsza rozmiar APK o 15-25% i obniża ryzyko wycieku kodu o 60%. Narzędzie stało się standardem w programowaniu na Androida i jest używane w milionach aplikacji na całym świecie.
Najważniejsze
ProGuard — swobodnie rozpowszechniane narzędzie do przetwarzania kodu bajtowego Java, opracowane przez firmę Guardsquare. Jest wbudowane w Android SDK i wykonuje trzy kluczowe funkcje: kompresję (shrinking), optymalizację (optimization) i obfuskację (obfuscation) kodu. ProGuard analizuje cały kod bajtowy aplikacji i jej zależności, określa nieużywane klasy i metody, usuwa je, a następnie zaciemnia pozostały kod.
ProGuard został stworzony przez Érica Lafourge'a w 2000 roku jako narzędzie do optymalizacji aplikacji Java. Wraz z pojawieniem się Androida w 2008 roku ProGuard został zintegrowany z Android SDK i stał się standardowym narzędziem do ochrony aplikacji. Według statystyk Guardsquare (2024), ProGuard jest używany w ponad 80% aplikacji w Google Play, w tym w aplikacjach największych banków i firm technologicznych.
ProGuard wykonuje przetwarzanie w czterech etapach. W pierwszym etapie (shrink) narzędzie analizuje punkty wejścia aplikacji i określa, które klasy, metody i pola są osiągalne podczas wykonywania. W drugim etapie (optimize) ProGuard przekształca kod bajtowy w celu zwiększenia wydajności. Trzeci etap (obfuscate) zmienia nazwy identyfikatorów. W końcowym etapie preverify dodaje metadane niezbędne do weryfikacji kodu bajtowego na maszynie wirtualnej.
Przyjrzyjmy się szczegółowo każdej z trzech głównych funkcji ProGuard: kompresji, optymalizacji i obfuskacji. Zrozumienie każdego mechanizmu pomoże skonfigurować narzędzie w optymalny sposób.
ProGuard analizuje graf wywołań od punktów wejścia (metoda main, Activity, BroadcastReceiver) i usuwa nieużywany kod. W typowym projekcie Android z bibliotekami takimi jak Retrofit, OkHttp i Gson kompresja może usunąć do 40% kodu bajtowego, w tym nieużywane metody bibliotek, kod debugowania i klasy testowe. To bezpośrednio zmniejsza rozmiar APK i skraca czas ładowania aplikacji.
Na etapie optymalizacji ProGuard wykonuje ponad 20 różnych przekształceń kodu bajtowego: inline'owanie krótkich metod, usuwanie nieużywanych parametrów, upraszczanie wyrażeń logicznych, łączenie identycznych bloków kodu. Na przykład krótkie gettery i settery mogą zostać zastąpione bezpośrednim dostępem do pola. Optymalizacja może przyspieszyć wykonywanie kodu o 5-15% w zależności od struktury aplikacji.
Obfuskacja w ProGuard działa poprzez zmianę nazw klas, metod i pól na krótkie sekwencje znaków: a, b, c, a.a, a.b i tak dalej. Wszystkie odwołania do zmienionych elementów są automatycznie aktualizowane w całym kodzie. Należy zauważyć, że obfuskacja nie zmienia zachowania programu, a jedynie utrudnia zrozumienie zdekompilowanego kodu. Biblioteki i publiczne API powinny być wyłączone z obfuskacji poprzez reguły keep.
// Przed obfuskacją ProGuard
public class LoginManager {
public User authenticateUser(String username, String password) {
// logika uwierzytelniania
}
}
// Po obfuskacji ProGuard
public class a {
public Object a(String b, String c) {
// ta sama logika z przemianowanymi identyfikatorami
}
}
Konfiguracja ProGuard — krytyczny etap konfiguracji kompilacji aplikacji Android. Nieprawidłowe reguły mogą prowadzić do usunięcia niezbędnych klas, a w konsekwencji do crasha w wersji release.
Aktywacja ProGuard w projekcie Android polega na ustawieniu flagi minifyEnabled na true dla typu kompilacji release. Standardowe reguły ProGuard są dostarczane wraz z Android SDK w pliku proguard-android-optimize.txt. Niestandardowe reguły dodaje się w osobnym pliku proguard-rules.pro. Podczas kompilacji ProGuard najpierw stosuje reguły standardowe, a następnie niestandardowe, co pozwala nadpisywać podstawową konfigurację.
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
Niestandardowy plik reguł zawiera dyrektywy specyficzne dla danego projektu. Typowe reguły obejmują zachowywanie klas używanych przez reflection, modeli danych do serializacji Gson/Moshi, interfejsów callback bibliotek i klas z adnotacjami specyficznymi. Każda dyrektywa zaczyna się od słowa kluczowego -keep, -dontwarn lub -keepclassmembers i określa wzorzec klasy, której ProGuard nie powinien modyfikować.
# Zachowaj modele danych dla Gson
-keep class com.example.data.model.** { *; }
# Zachowaj klasy używane przez reflection
-keep class * implements com.google.gson.TypeAdapterFactory
# Ignoruj ostrzeżenia bibliotek
-dontwarn okhttp3.internal.**
-dontwarn retrofit2.**
# Zachowaj enum-y (cecha ProGuard)
-keep class * extends java.lang.Enum { *; }
Gramatyka konfiguracji ProGuard obejmuje kilka kategorii dyrektyw, z których każda zarządza określonym aspektem przetwarzania. Omówmy główne z nich, niezbędne do prawidłowej konfiguracji.
| Dyrektywa | Przeznaczenie | Przykład |
|---|---|---|
| -keep | Całkowicie zachowaj klasę i jej składowe | -keep class com.example.MyClass |
| -keepclassmembers | Zachowaj tylko składowe klasy | -keepclassmembers class * { @Inject *; } |
| -dontwarn | Ignoruj ostrzeżenia | -dontwarn okhttp3.internal.** |
| -keepparameternames | Zachowaj nazwy parametrów metod | -keepparameternames |
| -keepattributes | Zachowaj atrybuty (adnotacje, EnclosingMethod) | -keepattributes *Annotation* |
| -dontoptimize | Wyłącz optymalizację | -dontoptimize |
ProGuard nie może statycznie przeanalizować kodu ładowanego przez reflection (Class.forName()), ServiceLoader lub dynamiczne ładowanie plików DEX. Jeśli klasa jest tworzona po nazwie łańcuchowej, ProGuard nie wie o jej istnieniu i może ją usunąć jako nieużywaną. Wszystkie takie klasy należy jawnie zachować przez -keep. To najczęstsza przyczyna crashy w wersjach release po włączeniu ProGuard.
Biblioteki często zawierają własne reguły ProGuard, które są automatycznie dodawane do kompilacji przez consumer-rules.pro, wbudowany w plik AAR. Android Gradle Plugin automatycznie stosuje te reguły podczas kompilacji. Deweloper musi tylko upewnić się, że wszystkie używane biblioteki dostarczają prawidłowe reguły i w razie potrzeby uzupełnić je w projekcie.
W przypadku wystąpienia błędów po włączeniu ProGuard użyj pliku mapping do deobfuskacji stack trace. Do diagnostyki służy klucz -whyareyoukeeping, który pokazuje przyczynę zachowania klasy w końcowej kompilacji. Tymczasowe wyłączenie -optimizationpasses i -obfuscation pozwala zlokalizować problem. Według Guardsquare, 80% problemów z ProGuard rozwiązuje się przez dodanie reguł -keep dla klas reflection.
Wraz z wydaniem Android Gradle Plugin 3.4 (2019) Google przedstawił R8 — następcę ProGuard, zintegrowanego bezpośrednio z kompilatorem D8/R8. Do 2023 roku R8 całkowicie zastąpił ProGuard w AGP 8.0, ale zrozumienie różnic architektonicznych jest ważne dla migracji projektów.
ProGuard działa jako osobne narzędzie, przetwarzające kod bajtowy Java (pliki .class) przed konwersją do DEX. R8 jest zintegrowany z kompilatorem DEX i przetwarza kod na niższym poziomie, co pozwala na optymalizacje niedostępne w ProGuard. R8 obsługuje również desugaring — konwersję cukru składniowego Java 8+ na kod wstecznie kompatybilny dla starszych poziomów API Androida.
Według Google Android Performance Team (2025), R8 zapewnia o 10-15% lepszą kompresję kodu w porównaniu z ProGuard przy tych samych regułach. R8 jest szybszy — czas kompilacji skraca się o 20-30%. Ponadto R8 usuwa więcej martwego kodu dzięki analizie na poziomie DEX, a nie plików class. R8 jest w pełni kompatybilny ze składnią reguł ProGuard, co czyni migrację przezroczystą dla dewelopera.
Przejście z ProGuard na R8 jest proste: w AGP 8.0+ R8 jest używany domyślnie. W starszych projektach należy usunąć ProGuard z classpath i zaktualizować gradle.properties: android.enableR8=true. Reguły ProGuard są kompatybilne z R8 bez zmian w większości przypadków. Zaleca się przetestowanie kompilacji release na wszystkich docelowych urządzeniach po przełączeniu, ponieważ R8 może usuwać kod, który ProGuard pozostawiał.
Często zadawane pytania
Najczęstsza przyczyna — usunięcie klas używanych przez reflection, serializację Gson/Moshi lub biblioteki z dynamicznym ładowaniem plików DEX. Rozwiązanie: dodaj reguły -keep dla wszystkich klas tworzonych przez Class.forName(), implementujących Parcelable, serializowanych przez JSON lub z adnotacją @Inject. Użyj pliku mapping do deobfuskacji stack trace i określenia usuniętej klasy z kompilacji.
Plik mapping znajduje się w build/outputs/mapping/release/mapping.txt po kompilacji. Format: oryginalna_nazwa -> zobfuskowana_nazwa -> typ. Android Studio obsługuje deobfuskację przez Build > Analyze APK: załaduj APK, wklej stack trace i otrzymaj czytelne nazwy klas. Dla CI/CD przechowuj pliki mapping dla każdej wersji w osobnym repozytorium lub przechowalni w chmurze.
Tak, ProGuard należy włączać tylko dla kompilacji release. Kompilacje debug używają minifyEnabled false, co przyspiesza kompilację i zachowuje czytelne nazwy klas dla debuggera. W trybie debug obfuskacja przeszkadza w debugowaniu i wykonywaniu krokowym, a kompresja spowalnia iteracje. Do testowania poprawności obfuskacji używaj kompilacji release na fizycznym urządzeniu.
Ostrzeżenia ProGuard (WARNING) wskazują na problemy, które nie powodują zatrzymania kompilacji, ale mogą wskazywać na potencjalne błędy wykonawcze. Jeśli ostrzeżenie nie prowadzi do crasha, dodaj -dontwarn dla odpowiedniej biblioteki. Jeśli ostrzeżenie jest związane z brakującą klasą, która nie jest używana w aplikacji, również użyj -dontwarn. Ignorowanie wszystkich ostrzeżeń naraz bez analizy nie jest zalecane.
ProGuard — darmowe narzędzie z podstawowymi funkcjami: kompresja, optymalizacja, zmiana nazw klas i metod. DexGuard — komercyjny produkt tej samej firmy Guardsquare, który dodaje zaciemnianie przepływu sterowania, szyfrowanie łańcuchów i zasobów, ochronę przed debugowaniem i obfuskację zasobów. DexGuard jest używany w bankowych aplikacjach i grach z wysokimi wymaganiami ochrony.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również