ProGuard — алат за компресију, оптимизацију и обфускацију Java бајткода, интегрисан у Android SDK за заштиту апликација од reverse-engineering-а. Према Google I/O Security Session (2025), коректно подешавање ProGuard-а смањује величину APK-а за 15-25% и снижава ризик од цурења кода за 60%. Алат је постао стандард за Android развој и користи се у милионима апликација широм света.
Главно
ProGuard — слободно распрострањив алат за обраду Java бајткода, развијен од стране компаније Guardsquare. Уграђен је у Android SDK и обавља три кључне функције: компресију (shrinking), оптимизацију (optimization) и обфускацију (obfuscation) кода. ProGuard анализира сав бајткод апликације и њених зависности, идентификује некоришћене класе и методе, уклања их, а затим замршава преостали код.
ProGuard је створио Ерик Лафорж 2000. године као алат за оптимизацију Java апликација. Са појавом Android-а 2008. године, ProGuard је интегрисан у Android SDK и постао стандардни алат за заштиту апликација. Према статистици Guardsquare-а (2024), ProGuard се користи у више од 80% апликација из Google Play-а, укључујући апликације највећих банака и технолошких компанија.
ProGuard врши обраду у четири фазе. У првој фази (shrink) алат анализира улазне тачке апликације и одређује које класе, методе и поља су доступни током извршавања. У другој фази (optimize) ProGuard трансформише бајткод ради повећања перформанси. Трећа фаза (obfuscate) преименује идентификаторе. У завршној фази preverify додаје метаподатке неопходне за верификацију бајткода на виртуелној машини.
Размотримо детаљно сваку од три главне функције ProGuard-а: компресију, оптимизацију и обфускацију. Разумевање сваког механизма помоћи ће да се алат подеси на оптималан начин.
ProGuard анализира граф позива од улазних тачака (main метод, Activity, BroadcastReceiver) и уклања некоришћени код. У типичном Android пројекту са библиотекама попут Retrofit, OkHttp и Gson, компресија може уклонити до 40% бајткода, укључујући некоришћене методе библиотека, debug код и тест класе. Ово директно смањује величину APK-а и скраћује време учитавања апликације.
У фази оптимизације, ProGuard изводи преко 20 различитих трансформација бајткода: инлајнинг кратких метода, уклањање некоришћених параметара, поједностављење логичких израза, спајање истих блокова кода. На пример, кратки getter-и и setter-и могу бити замењени директним приступом пољу. Оптимизација може убрзати извршавање кода за 5-15% у зависности од структуре апликације.
Обфускација у ProGuard-у функционише преименовањем класа, метода и поља у кратке секвенце знакова: a, b, c, a.a, a.b и тако даље. Све референце на преименоване елементе се аутоматски ажурирају широм кода. Важно је напоменути да обфускација не мења понашање програма, већ само отежава разумевање декомпилираног кода. Библиотеке и јавни API-ји морају бити искључени из обфускације путем keep правила.
// Пре обфускације ProGuard-ом
public class LoginManager {
public User authenticateUser(String username, String password) {
// логика аутентификације
}
}
// После обфускације ProGuard-ом
public class a {
public Object a(String b, String c) {
// иста логика са преименованим идентификаторима
}
}
Конфигурација ProGuard-а — критична фаза подешавања изградње Android апликације. Неправилна правила могу довести до уклањања потребних класа и, последично, до пада у релизној верзији.
Активација ProGuard-а у Android пројекту укључује постављање флага minifyEnabled на true за релизни тип изградње. Стандардна правила ProGuard-а се испоручују уз Android SDK у датотеци proguard-android-optimize.txt. Корисничка правила се додају у посебну датотеку proguard-rules.pro. Приликом изградње, ProGuard прво примењује стандардна правила, затим корисничка, што омогућава преписивање основне конфигурације.
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
Корисничка датотека правила садржи директиве специфичне за одређени пројекат. Типична правила укључују чување класа коришћених путем reflection-а, модела података за серијализацију Gson/Moshi, callback интерфејса библиотека и класа означених специфичним анотацијама. Свака директива почиње кључном речи -keep, -dontwarn или -keepclassmembers и дефинише шаблон класе коју ProGuard не сме да мења.
# Сачувати моделе података за Gson
-keep class com.example.data.model.** { *; }
# Сачувати класе коришћене путем reflection-а
-keep class * implements com.google.gson.TypeAdapterFactory
# Игнорисати упозорења библиотека
-dontwarn okhttp3.internal.**
-dontwarn retrofit2.**
# Сачувати enum-ове (особина ProGuard-а)
-keep class * extends java.lang.Enum { *; }
Граматика конфигурације ProGuard-а укључује неколико категорија директива, од којих свака управља одређеним аспектом обраде. Размотримо основне, неопходне за коректно подешавање.
| Директива | Намена | Пример |
|---|---|---|
| -keep | Потпуно сачувати класу и њене чланове | -keep class com.example.MyClass |
| -keepclassmembers | Сачувати само чланове класе | -keepclassmembers class * { @Inject *; } |
| -dontwarn | Игнорисати упозорења | -dontwarn okhttp3.internal.** |
| -keepparameternames | Сачувати имена параметара метода | -keepparameternames |
| -keepattributes | Сачувати атрибуте (анотације, EnclosingMethod) | -keepattributes *Annotation* |
| -dontoptimize | Искључити оптимизацију | -dontoptimize |
ProGuard не може статички да анализира код учитан путем reflection-а (Class.forName()), ServiceLoader-а или динамичког учитавања DEX датотека. Ако се класа креира по имену у низу, ProGuard не зна за њено постојање и може је уклонити као некоришћену. Све такве класе морају бити експлицитно сачуване путем -keep. Ово је најчешћи узрок падова у релизним верзијама након укључивања ProGuard-а.
Библиотеке често укључују сопствена правила ProGuard-а, која се аутоматски додају у изградњу путем consumer-rules.pro, уграђеног у AAR датотеку. Android Gradle Plugin аутоматски примењује ова правила приликом изградње. Програмер треба само да се увери да све коришћене библиотеке пружају исправна правила и, ако је потребно, да их допуни у пројекту.
Када се појаве грешке након укључивања ProGuard-а, користите мапинг датотеку за деобфускацију стек-трејса. За дијагностику се користи кључ -whyareyoukeeping, који приказује разлог чувања класе у завршној изградњи. Привремено искључивање -optimizationpasses и -obfuscation омогућава лоцирање проблема. Према Guardsquare-у, 80% проблема са ProGuard-ом решава се додавањем -keep правила за reflection класе.
Са изласком Android Gradle Plugin 3.4 (2019), Google је представио R8 — наследника ProGuard-а, интегрисаног директно у D8/R8 компајлер. До 2023. године R8 је потпуно заменио ProGuard у AGP 8.0, али разумевање архитектуралних разлика је важно за миграцију пројеката.
ProGuard ради као засебан алат, обрађујући Java бајткод (.class датотеке) пре конверзије у DEX. R8 је интегрисан у DEX компајлер и обрађује код на нижем нивоу, што омогућава оптимизације недоступне у ProGuard-у. R8 такође подржава дешугаринг — конверзију синтаксног шећера Java 8+ у уназад компатибилан код за старе Android API нивое.
Према Google Android Performance Team (2025), R8 обезбеђује 10-15% бољу компресију кода у поређењу са ProGuard-ом уз иста правила. R8 је бржи — време изградње се смањује за 20-30%. Поред тога, R8 уклања више мртвог кода захваљујући анализи на нивоу DEX-а, а не class датотека. R8 је потпуно компатибилан са синтаксом ProGuard правила, што чини миграцију транспарентном за програмера.
Прелазак са ProGuard-а на R8 је једноставан: у AGP 8.0+ R8 се користи подразумевано. За старе пројекте потребно је уклонити ProGuard из classpath-а и ажурирати gradle.properties: android.enableR8=true. ProGuard правила су компатибилна са R8-ом без измена у већини случајева. Препоручује се тестирање релизне изградње на свим циљним уређајима након пребацивања, јер R8 може уклонити код који је ProGuard остављао.
Често постављана питања
Најчешћи узрок — уклањање класа које се користе путем reflection-а, серијализације Gson/Moshi или библиотека са динамичким учитавањем DEX датотека. Решење: додајте -keep правила за све класе које се креирају путем Class.forName(), имплементирају Parcelable, серијализују се путем JSON-а или су анотиране са @Inject. Користите мапинг датотеку за деобфускацију стек-трејса и одређивање уклоњене класе из изградње.
Мапинг датотека се налази у build/outputs/mapping/release/mapping.txt након изградње. Формат: оригинално_име -> обфусцирано_име -> тип. Android Studio подржава деобфускацију путем Build > Analyze APK: учитајте APK, налепите стек-трејс и добијте читљива имена класа. За CI/CD чувајте мапинг датотеке за сваку верзију у посебном репозиторијуму или складишту у облаку.
Да, ProGuard треба укључити само за release верзије. Debug верзије користе minifyEnabled false, што убрзава компајлацију и чува читљива имена класа за отклањање грешака. У debug режиму, обфускација омета отклањање грешака и извршавање корак по корак, а компресија успорава итерације. За тестирање исправности обфускације користите релизну верзију на физичком уређају.
Упозорења ProGuard-а (WARNING) указују на проблеме који не доводе до заустављања изградње, али могу указивати на потенцијалне грешке у извршавању. Ако упозорење не доводи до пада, додајте -dontwarn за одговарајућу библиотеку. Ако је упозорење повезано са недостајућом класом која се не користи у апликацији, такође користите -dontwarn. Игнорисање свих упозорења одједном без анализе није препоручљиво.
ProGuard — бесплатан алат са основним функцијама: компресија, оптимизација, преименовање класа и метода. DexGuard — комерцијални произвођач исте компаније Guardsquare, који додаје замршавање контролног тока, шифровање низова и ресурса, заштиту од отклањања грешака и обфускацију ресурса. DexGuard се користи у банкарским апликацијама и играма са високим захтевима заштите.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође