ProGuard — cos'è, funzionalità e configurazione dell'offuscamento

Autore: IT Sectr Pubblicato: 2026-04-03 Tempo di lettura: 8 min

ProGuard è uno strumento di compressione, ottimizzazione e offuscamento del bytecode Java, integrato nell'Android SDK per proteggere le applicazioni dal reverse engineering. Secondo Google I/O Security Session (2025), la corretta configurazione di ProGuard riduce le dimensioni dell'APK del 15-25% e diminuisce il rischio di perdita di codice del 60%. Lo strumento è diventato lo standard per lo sviluppo Android ed è utilizzato in milioni di applicazioni in tutto il mondo.

Punti chiave

  • ProGuard è uno strumento per comprimere, ottimizzare e offuscare il bytecode Java nelle applicazioni Android.
  • La compressione rimuove classi, metodi e campi inutilizzati, riducendo le dimensioni dell'APK.
  • L'offuscamento rinomina gli identificatori in nomi brevi senza senso per proteggere dalla decompilazione.
  • L'ottimizzazione esegue l'inlining dei metodi e la semplificazione a livello di bytecode.
  • Il file di mapping consente di deoffuscare i rapporti di crash ed è essenziale per supportare le build di rilascio.

Cos'è ProGuard?

ProGuard è uno strumento distribuito gratuitamente per l'elaborazione del bytecode Java, sviluppato da Guardsquare. È integrato nell'Android SDK e svolge tre funzioni principali: compressione, ottimizzazione e offuscamento del codice. ProGuard analizza tutto il bytecode dell'applicazione e delle sue dipendenze, identifica classi e metodi inutilizzati, li rimuove e quindi offusca il codice rimanente.

Storia e posizionamento

ProGuard è stato creato da Eric Lafortune nel 2000 come strumento di ottimizzazione delle applicazioni Java. Con l'avvento di Android nel 2008, ProGuard è stato integrato nell'Android SDK ed è diventato lo strumento standard per la protezione delle applicazioni. Secondo le statistiche di Guardsquare (2024), ProGuard è utilizzato in oltre l'80% delle applicazioni su Google Play, incluse le app delle principali banche e aziende tecnologiche.

Come ProGuard elabora il codice

ProGuard esegue l'elaborazione in quattro fasi. Nella prima fase (compressione), lo strumento analizza i punti di ingresso dell'applicazione e determina quali classi, metodi e campi sono raggiungibili durante l'esecuzione. Nella seconda fase (ottimizzazione), ProGuard trasforma il bytecode per migliorare le prestazioni. La terza fase (offuscamento) rinomina gli identificatori. Nella fase finale, preverify aggiunge i metadati necessari per la verifica del bytecode sulla macchina virtuale.

Funzionalità principali di ProGuard

Esaminiamo in dettaglio ciascuna delle tre funzioni principali di ProGuard: compressione, ottimizzazione e offuscamento. Comprendere ogni meccanismo aiuterà a configurare lo strumento in modo ottimale.

Compressione del codice

ProGuard analizza il grafo delle chiamate dai punti di ingresso (metodo main, Activity, BroadcastReceiver) e rimuove il codice inutilizzato. In un tipico progetto Android con librerie come Retrofit, OkHttp e Gson, la compressione può rimuovere fino al 40% del bytecode, inclusi metodi di libreria inutilizzati, codice di debug e classi di test. Questo riduce direttamente le dimensioni dell'APK e accorcia i tempi di caricamento dell'applicazione.

Ottimizzazione

Nella fase di ottimizzazione, ProGuard esegue oltre 20 diverse trasformazioni del bytecode: inlining di metodi brevi, rimozione di parametri inutilizzati, semplificazione di espressioni logiche, fusione di blocchi di codice identici. Ad esempio, getter e setter brevi possono essere sostituiti con accesso diretto al campo. L'ottimizzazione può accelerare l'esecuzione del codice del 5-15% a seconda della struttura dell'applicazione.

Offuscamento

L'offuscamento in ProGuard funziona rinominando classi, metodi e campi in brevi sequenze di caratteri: a, b, c, a.a, a.b e così via. Tutti i riferimenti agli elementi rinominati vengono automaticamente aggiornati in tutto il codice. È importante notare che l'offuscamento non modifica il comportamento del programma, rende solo più difficile la comprensione del codice decompilato. Le librerie e le API pubbliche devono essere escluse dall'offuscamento tramite le regole keep.

java
// Prima dell'offuscamento ProGuard
public class LoginManager {
    public User authenticateUser(String username, String password) {
        // logica di autenticazione
    }
}

// Dopo l'offuscamento ProGuard
public class a {
    public Object a(String b, String c) {
        // la stessa logica con identificatori rinominati
    }
}

Configurazione di ProGuard nel progetto Android

La configurazione di ProGuard è un passaggio critico nell'impostazione della build dell'applicazione Android. Regole errate possono portare alla rimozione di classi necessarie e, di conseguenza, a crash nella versione di rilascio.

Configurazione di base in build.gradle

L'attivazione di ProGuard in un progetto Android comporta l'impostazione del flag minifyEnabled su true per il tipo di build di rilascio. Le regole standard di ProGuard sono fornite con l'Android SDK nel file proguard-android-optimize.txt. Le regole personalizzate vengono aggiunte in un file separato proguard-rules.pro. Durante la build, ProGuard applica prima le regole standard, poi quelle personalizzate, consentendo di sostituire la configurazione di base.

groovy
android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile(
                'proguard-android-optimize.txt'
            ), 'proguard-rules.pro'
        }
    }
}

Il file proguard-rules.pro

Il file di regole personalizzato contiene direttive specifiche per il progetto. Le regole tipiche includono la conservazione delle classi utilizzate tramite reflection, dei modelli di dati per la serializzazione Gson/Moshi, delle interfacce di callback delle librerie e delle classi annotate con annotazioni specifiche. Ogni direttiva inizia con una parola chiave -keep, -dontwarn o -keepclassmembers e definisce un pattern della classe che ProGuard non deve modificare.

properties
# Conservare i modelli di dati per Gson
-keep class com.example.data.model.** { *; }

# Conservare le classi utilizzate tramite reflection
-keep class * implements com.google.gson.TypeAdapterFactory

# Ignorare gli avvisi delle librerie
-dontwarn okhttp3.internal.**
-dontwarn retrofit2.**

# Conservare gli enum (funzionalità ProGuard)
-keep class * extends java.lang.Enum { *; }

Regole di ProGuard: keep, dontwarn e altre

La grammatica di configurazione di ProGuard include diverse categorie di direttive, ciascuna delle quali gestisce un aspetto specifico dell'elaborazione. Vediamo le principali necessarie per una configurazione corretta.

DirettivaScopoEsempio
-keepConservare completamente la classe e i suoi membri-keep class com.example.MyClass
-keepclassmembersConservare solo i membri della classe-keepclassmembers class * { @Inject *; }
-dontwarnIgnorare gli avvisi-dontwarn okhttp3.internal.**
-keepparameternamesConservare i nomi dei parametri dei metodi-keepparameternames
-keepattributesConservare gli attributi (annotazioni, EnclosingMethod)-keepattributes *Annotation*
-dontoptimizeDisabilitare l'ottimizzazione-dontoptimize

Reflection e caricamento dinamico

ProGuard non può analizzare staticamente il codice caricato tramite reflection (Class.forName()), ServiceLoader o caricamento dinamico di file DEX. Se una classe viene creata dal suo nome stringa, ProGuard non conosce la sua esistenza e può rimuoverla come inutilizzata. Tutte queste classi devono essere esplicitamente conservate tramite -keep. Questa è la causa più comune di crash nelle build di rilascio dopo l'attivazione di ProGuard.

Librerie e dipendenze AAR

Le librerie spesso includono le proprie regole ProGuard, che vengono automaticamente aggiunte alla build tramite consumer-rules.pro incorporato nel file AAR. Android Gradle Plugin applica automaticamente queste regole durante la build. Lo sviluppatore deve solo assicurarsi che tutte le librerie utilizzate forniscano regole corrette e, se necessario, integrarle nel progetto.

Debug dei problemi di ProGuard

Quando si verificano errori dopo l'attivazione di ProGuard, utilizzare il file di mapping per deoffuscare la traccia dello stack. Per la diagnostica, utilizzare la chiave -whyareyoukeeping, che mostra il motivo per cui una classe viene conservata nella build di output. La disabilitazione temporanea di -optimizationpasses e -obfuscation consente di localizzare il problema. Secondo Guardsquare, l'80% dei problemi con ProGuard si risolve aggiungendo regole -keep per le classi di reflection.

ProGuard vs R8: confronto e migrazione

Con il rilascio di Android Gradle Plugin 3.4 (2019), Google ha introdotto R8 — il successore di ProGuard, integrato direttamente nel compilatore D8/R8. Entro il 2023, R8 ha completamente sostituito ProGuard in AGP 8.0, ma comprendere le differenze architetturali è importante per la migrazione dei progetti.

Differenze architetturali

ProGuard funziona come uno strumento separato che elabora il bytecode Java (file .class) prima della conversione in DEX. R8 è integrato nel compilatore DEX ed elabora il codice a un livello inferiore, consentendo ottimizzazioni non disponibili in ProGuard. R8 supporta anche il desugaring — la conversione dello zucchero sintattico Java 8+ in codice retrocompatibile per vecchi livelli API Android.

Vantaggi di R8

Secondo Google Android Performance Team (2025), R8 offre una compressione del codice migliore del 10-15% rispetto a ProGuard con regole identiche. R8 è più veloce — il tempo di build si riduce del 20-30%. Inoltre, R8 rimuove più codice morto grazie all'analisi a livello DEX anziché a livello di file di classe. R8 è completamente compatibile con la sintassi delle regole ProGuard, rendendo la migrazione trasparente per lo sviluppatore.

Processo di migrazione

Il passaggio da ProGuard a R8 è semplice: in AGP 8.0+, R8 viene utilizzato per impostazione predefinita. Per i progetti più vecchi, è necessario rimuovere ProGuard dal classpath e aggiornare gradle.properties: android.enableR8=true. Le regole ProGuard sono compatibili con R8 senza modifiche nella maggior parte dei casi. Si consiglia di testare la build di rilascio su tutti i dispositivi target dopo il passaggio, poiché R8 potrebbe rimuovere codice che ProGuard conservava.

Domande frequenti

Perché l'app si blocca sul dispositivo dopo aver attivato ProGuard?

La causa più comune è la rimozione di classi utilizzate tramite reflection, serializzazione Gson/Moshi o librerie con caricamento dinamico di file DEX. Soluzione: aggiungere regole -keep per tutte le classi create tramite Class.forName(), che implementano Parcelable, serializzate tramite JSON o annotate con @Inject. Utilizzare il file di mapping per la deoffuscazione della traccia dello stack e l'identificazione della classe rimossa dalla build.

Come leggere correttamente il file di mapping di ProGuard?

Il file di mapping si trova in build/outputs/mapping/release/mapping.txt dopo la build. Formato: nome_originale -> nome_offuscato -> tipo. Android Studio supporta la deoffuscazione tramite Build > Analyze APK: carica l'APK, incolla la traccia dello stack e ottieni nomi di classe leggibili. Per CI/CD, conserva i file di mapping per ogni versione in un repository separato o archivio cloud.

Bisogna disabilitare ProGuard durante il debug delle build di debug?

Sì, ProGuard dovrebbe essere attivato solo per le build di rilascio. Le build di debug usano minifyEnabled false, che accelera la compilazione e preserva nomi di classe leggibili per il debugger. In modalità debug, l'offuscamento interferisce con il debug e l'esecuzione passo-passo, mentre la compressione rallenta le iterazioni. Per testare la correttezza dell'offuscamento, utilizzare una build di rilascio su un dispositivo fisico.

Cosa fare con gli avvisi e gli errori di ProGuard?

Gli avvisi di ProGuard (WARNING) indicano problemi che non fermano la build ma possono segnalare potenziali errori di runtime. Se un avviso non porta a un crash, aggiungere -dontwarn per la libreria corrispondente. Se un avviso è correlato a una classe mancante che non viene utilizzata nell'applicazione, utilizzare anche -dontwarn. Ignorare tutti gli avvisi contemporaneamente senza discernimento non è raccomandato.

In cosa ProGuard si differenzia da DexGuard per Android?

ProGuard è uno strumento gratuito con funzionalità di base: compressione, ottimizzazione, rinomina di classi e metodi. DexGuard è un prodotto commerciale dello stesso Guardsquare che aggiunge offuscamento del flusso di controllo, crittografia di stringhe e risorse, protezione anti-debug e offuscamento delle risorse. DexGuard viene utilizzato in applicazioni bancarie e giochi con elevati requisiti di sicurezza.

Riepilogo

  • ProGuard è lo strumento standard di compressione, ottimizzazione e offuscamento per le applicazioni Android.
  • La compressione rimuove fino al 40% del bytecode inutilizzato, riducendo significativamente le dimensioni finali dell'APK.
  • L'offuscamento rinomina classi e metodi, proteggendo dalla decompilazione.
  • Le regole keep sono obbligatorie per le classi utilizzate tramite reflection e serializzazione.
  • Il file di mapping è necessario per la deoffuscazione dei rapporti di crash nelle build di rilascio.
  • R8 ha sostituito ProGuard in AGP 8.0, offrendo una migliore compressione del codice e una maggiore velocità di build.
  • Testare la build di rilascio con ProGuard su dispositivi fisici è obbligatorio prima della pubblicazione nello store.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche