ProGuard — nástroj pro kompresi, optimalizaci a obfuskatci Java bajtového kódu, integrovaný do Android SDK pro ochranu aplikací před reverse-engineeringem. Podle Google I/O Security Session (2025), správné nastavení ProGuardu snižuje velikost APK o 15–25 % a snižuje riziko úniku kódu o 60 %. Nástroj se stal standardem pro vývoj na Androidu a používá se v milionech aplikací po celém světě.
Hlavní body
ProGuard — volně šířený nástroj pro zpracování Java bajtového kódu, vyvinutý společností Guardsquare. Je vestavěný do Android SDK a vykonává tři klíčové funkce: kompresi (shrinking), optimalizaci (optimization) a obfuskatci (obfuscation) kódu. ProGuard analyzuje veškerý bajtový kód aplikace a jejích závislostí, identifikuje nepoužívané třídy a metody, odstraňuje je a poté zatemňuje zbývající kód.
ProGuard vytvořil Éric Lafourge v roce 2000 jako nástroj pro optimalizaci Java aplikací. S příchodem Androidu v roce 2008 byl ProGuard integrován do Android SDK a stal se standardním nástrojem pro ochranu aplikací. Podle statistik Guardsquare (2024) je ProGuard používán ve více než 80 % aplikací v Google Play, včetně aplikací největších bank a technologických společností.
ProGuard provádí zpracování ve čtyřech fázích. V první fázi (shrink) nástroj analyzuje vstupní body aplikace a určuje, které třídy, metody a pole jsou dosažitelné během spouštění. Ve druhé fázi (optimize) ProGuard transformuje bajtový kód pro zvýšení výkonu. Třetí fáze (obfuscate) přejmenovává identifikátory. V závěrečné fázi preverify přidává metadata nezbytná pro ověření bajtového kódu na virtuálním stroji.
Pojďme podrobně prozkoumat každou ze tří hlavních funkcí ProGuardu: kompresi, optimalizaci a obfuskatci. Pochopení každého mechanismu pomůže nastavit nástroj optimálním způsobem.
ProGuard analyzuje graf volání od vstupních bodů (hlavní metoda, Activity, BroadcastReceiver) a odstraňuje nepoužívaný kód. V typickém Android projektu s knihovnami jako Retrofit, OkHttp a Gson může komprese odstranit až 40 % bajtového kódu, včetně nepoužívaných metod knihoven, debug kódu a testovacích tříd. To přímo zmenšuje velikost APK a zkracuje dobu načítání aplikace.
Ve fázi optimalizace provádí ProGuard více než 20 různých transformací bajtového kódu: inlining krátkých metod, odstraňování nepoužívaných parametrů, zjednodušování logických výrazů, slučování identických bloků kódu. Například krátké gettery a settery mohou být nahrazeny přímým přístupem k poli. Optimalizace může zrychlit provádění kódu o 5–15 % v závislosti na struktuře aplikace.
Obfuskace v ProGuardu funguje přejmenováváním tříd, metod a polí na krátké sekvence znaků: a, b, c, a.a, a.b a tak dále. Všechny reference na přejmenované prvky jsou automaticky aktualizovány v celém kódu. Je důležité poznamenat, že obfuskace nemění chování programu, pouze ztěžuje porozumění dekompilovanému kódu. Knihovny a veřejná API musí být z obfuskace vyloučeny pomocí pravidel keep.
// Před obfuskatcí ProGuardem
public class LoginManager {
public User authenticateUser(String username, String password) {
// logika autentizace
}
}
// Po obfuskatci ProGuardem
public class a {
public Object a(String b, String c) {
// stejná logika s přejmenovanými identifikátory
}
}
Konfigurace ProGuardu je kritickou fází nastavení sestavení Android aplikace. Nesprávná pravidla mohou vést k odstranění nezbytných tříd a v důsledku toho k pádu v release verzi.
Aktivace ProGuardu v Android projektu zahrnuje nastavení příznaku minifyEnabled na true pro release typ sestavení. Standardní pravidla ProGuardu jsou dodávána s Android SDK v souboru proguard-android-optimize.txt. Uživatelská pravidla se přidávají do samostatného souboru proguard-rules.pro. Při sestavení ProGuard nejprve aplikuje standardní pravidla, poté uživatelská, což umožňuje přepisovat základní konfiguraci.
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
Uživatelský soubor pravidel obsahuje direktivy specifické pro konkrétní projekt. Typická pravidla zahrnují zachování tříd používaných přes reflection, datových modelů pro serializaci Gson/Moshi, callback rozhraní knihoven a tříd označených specifickými anotacemi. Každá direktiva začíná klíčovým slovem -keep, -dontwarn nebo -keepclassmembers a definuje vzor třídy, kterou ProGuard nesmí měnit.
# Zachovat datové modely pro Gson
-keep class com.example.data.model.** { *; }
# Zachovat třídy používané přes reflection
-keep class * implements com.google.gson.TypeAdapterFactory
# Ignorovat varování knihoven
-dontwarn okhttp3.internal.**
-dontwarn retrofit2.**
# Zachovat enumy (vlastnost ProGuardu)
-keep class * extends java.lang.Enum { *; }
Gramatika konfigurace ProGuardu zahrnuje několik kategorií direktiv, z nichž každá řídí určitý aspekt zpracování. Podívejme se na hlavní, nezbytné pro správné nastavení.
| Direktiva | Účel | Příklad |
|---|---|---|
| -keep | Zcela zachovat třídu a její členy | -keep class com.example.MyClass |
| -keepclassmembers | Zachovat pouze členy třídy | -keepclassmembers class * { @Inject *; } |
| -dontwarn | Ignorovat varování | -dontwarn okhttp3.internal.** |
| -keepparameternames | Zachovat názvy parametrů metod | -keepparameternames |
| -keepattributes | Zachovat atributy (anotace, EnclosingMethod) | -keepattributes *Annotation* |
| -dontoptimize | Vypnout optimalizaci | -dontoptimize |
ProGuard nemůže staticky analyzovat kód načítaný přes reflection (Class.forName()), ServiceLoader nebo dynamické načítání DEX souborů. Pokud je třída vytvořena podle řetězcového názvu, ProGuard o její existenci neví a může ji odstranit jako nepoužívanou. Všechny takové třídy musí být explicitně zachovány pomocí -keep. To je nejčastější příčina pádů v release verzích po zapnutí ProGuardu.
Knihovny často obsahují vlastní pravidla ProGuardu, která jsou automaticky přidávána do sestavení přes consumer-rules.pro, vestavěný v AAR souboru. Android Gradle Plugin tato pravidla automaticky aplikuje při sestavení. Vývojář se pouze musí ujistit, že všechny používané knihovny poskytují správná pravidla, a v případě potřeby je doplnit v projektu.
Při výskytu chyb po zapnutí ProGuardu použijte mapovací soubor pro deobfuskatci stack trace. Pro diagnostiku slouží klíč -whyareyoukeeping, který ukazuje důvod zachování třídy ve výsledném sestavení. Dočasné vypnutí -optimizationpasses a -obfuscation umožňuje lokalizovat problém. Podle Guardsquare je 80 % problémů s ProGuardem vyřešeno přidáním pravidel -keep pro reflection třídy.
S vydáním Android Gradle Plugin 3.4 (2019) Google představil R8 — nástupce ProGuardu, integrovaný přímo do kompilátoru D8/R8. Do roku 2023 R8 zcela nahradil ProGuard v AGP 8.0, ale pochopení architektonických rozdílů je důležité pro migraci projektů.
ProGuard funguje jako samostatný nástroj, zpracovávající Java bajtový kód (.class soubory) před převodem do DEX. R8 je integrován do DEX kompilátoru a zpracovává kód na nižší úrovni, což umožňuje optimalizace nedostupné v ProGuardu. R8 také podporuje desugaring — převod syntaktického cukru Java 8+ na zpětně kompatibilní kód pro staré úrovně API Androidu.
Podle Google Android Performance Team (2025) poskytuje R8 o 10–15 % lepší kompresi kódu ve srovnání s ProGuardem při stejných pravidlech. R8 je rychlejší — doba sestavení se zkracuje o 20–30 %. Kromě toho R8 odstraňuje více mrtvého kódu díky analýze na úrovni DEX, nikoli class souborů. R8 je plně kompatibilní se syntaxí pravidel ProGuardu, což činí migraci průhlednou pro vývojáře.
Přechod z ProGuardu na R8 je jednoduchý: v AGP 8.0+ se R8 používá ve výchozím nastavení. U starých projektů je třeba odstranit ProGuard z classpath a aktualizovat gradle.properties: android.enableR8=true. Pravidla ProGuardu jsou ve většině případů beze změn kompatibilní s R8. Doporučuje se otestovat release sestavení na všech cílových zařízeních po přepnutí, protože R8 může odstranit kód, který ProGuard zachovával.
Často kladené otázky
Nejčastější příčina — odstranění tříd používaných přes reflection, serializaci Gson/Moshi nebo knihovny s dynamickým načítáním DEX souborů. Řešení: přidejte pravidla -keep pro všechny třídy, které jsou vytvářeny přes Class.forName(), implementují Parcelable, jsou serializovány přes JSON nebo mají anotaci @Inject. Použijte mapovací soubor pro deobfuskatci stack trace a určení odstraněné třídy ze sestavení.
Mapovací soubor se nachází v build/outputs/mapping/release/mapping.txt po sestavení. Formát: původní_název -> obfuskovaný_název -> typ. Android Studio podporuje deobfuskatci přes Build > Analyze APK: nahrajte APK, vložte stack trace a získejte čitelné názvy tříd. Pro CI/CD ukládejte mapovací soubory pro každou verzi do samostatného repozitáře nebo cloudového úložiště.
Ano, ProGuard by měl být zapnut pouze pro release sestavení. Debug sestavení používají minifyEnabled false, což urychluje kompilaci a zachovává čitelné názvy tříd pro ladicí nástroj. V debug režimu obfuskace překáží ladění a krokování a komprese zpomaluje iterace. Pro testování správnosti obfuskace použijte release sestavení na fyzickém zařízení.
Varování ProGuardu (WARNING) označují problémy, které nezastavují sestavení, ale mohou naznačovat potenciální chyby za běhu. Pokud varování nevede k pádu, přidejte -dontwarn pro příslušnou knihovnu. Pokud varování souvisí s chybějící třídou, která není v aplikaci používána, použijte také -dontwarn. Ignorování všech varování najednou bez analýzy se nedoporučuje.
ProGuard — bezplatný nástroj se základními funkcemi: komprese, optimalizace, přejmenovávání tříd a metod. DexGuard — komerční produkt od stejné společnosti Guardsquare, který přidává zatemňování řídicího toku, šifrování řetězců a zdrojů, ochranu před laděním a obfuskatci zdrojů. DexGuard se používá v bankovních aplikacích a hrách s vysokými požadavky na ochranu.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také