10

Sto spostando un progetto da Ant a Gradle, ma c'è qualcosa che non riesco proprio a capire.Passaggio a Gradle: perché è necessario mantenere nascoste le visualizzazioni personalizzate?


FATTI

Dopo la costruzione di un APK rilascio (cioè offuscato), ho notato che l'applicazione è stata arrestando male. L'errore può essere riassunta da questo:

java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet] 

un debug (vale a dire, non offuscato) APK funziona bene, così ho indovinato aveva a che fare con la mia ProGuard/DexGuard configurazione.

ho cercato di mantenere il riferimento di classe aggiungendo la seguente dichiarazione:

-keep class com.mypackage.MyCustomView 

e, di conseguenza, il rilascio APK funziona bene. Poi ho fatto qualche ricerca e ho provato questo in modo più preciso la configurazione ProGuard/DexGuard:

-keep public class * extends android.view.View { 
    public <init>(android.content.Context); 
    public <init>(android.content.Context, android.util.AttributeSet); 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
    public void set*(...); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

che funziona anche, ed è classe indipendente.


DOMANDA

mi chiedo:

  1. Perché non hanno a che fare con è durante l'utilizzo di Ant?
  2. Qual è il motivo esatto per cui viene visualizzato l'errore? (Segue rispondere alla prima domanda)

RISPOSTA

La risposta di @Blundell era sostanzialmente corretta. Mi risulta mancava una linea dalla configurazione build.gradle:

android { 
    ... 
    buildTypes { 
    debug { 
     ... 
    } 
    release { 
     proguardFile getDefaultDexGuardFile('dexguard-release.pro') # <----- this line 
     proguardFile 'dexguard-project.txt' 
    } 
    } 
} 

Risulta che la linea sia effettivamente obbligatoria, dal momento che serve come un insieme base regole per ProGuard/DexGuard. In realtà, questo è parte del file dexguard-release.pro:

-keepclassmembers !abstract class !com.google.ads.** extends android.view.View { 
    public <init>(android.content.Context); 
    public <init>(android.content.Context, android.util.AttributeSet); 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
    public void set*(...); 
} 

-keepclassmembers !abstract class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

-keepclassmembers class * extends android.content.Context { 
    public void *(android.view.View); 
} 

ho trovato la documentazione un po 'troppo vago su questo, spero che possa essere redatto per eliminare qualsiasi ambiguità che potrebbe avere. Tutto sommato, colpa mia.

+0

come/dove si crea la visualizzazione personalizzata? – pskink

+0

I costruttori devono essere mantenuti perché il 'LayoutInflater' li sta usando, ma questo non può essere dedotto dall'analisi statica della sola fonte. Immagino che la tua vera domanda sia: perché la configurazione predefinita di ProGuard/DexGuard che prima era parte dell'SDK non è stata utilizzata? La mia ipotesi è che questo è dovuto ai recenti cambiamenti nel plugin Gradle, insieme a 'runProguard' che viene rinominato e ad altre cose del genere. Se stai utilizzando ProGuard dall'SDK, controlla con il gruppo Google adt-dev. Se stai usando DexGuard, controlla il portale di download, ci sono stati alcuni aggiornamenti recenti in rapida successione. – Barend

+0

@Barend Non sono sicuro di cosa 'perché la configurazione predefinita di ProGuard/DexGuard che prima era parte dell'SDK non utilizzata 'dovrebbe significare. Mi chiedo perché ci sia un comportamento diverso in Ant e Gradle, poiché entrambi utilizzano la stessa versione di DexGuard e stanno entrambi utilizzando lo stesso file di configurazione. – Sebastiano

risposta

3

Molto probabilmente Formica stava usando un file di configurazione diversa,

Anche con Gradle è necessario dichiarare esplicitamente che si desidera utilizzare anche il file di configurazione Proguard Android vale a direutilizzare più file di regole in questo modo:

proguardFile getDefaultProguardFile('proguard-android.txt') 
    proguardFile 'your/sepcific/folder/proguard.cfg' 

(mi ricordo Ant mai usato un file Proguard SDK e ha usato per essere raccomandato per copiare tutto il config di diametro).

+0

No, sto (ancora) usando lo stesso file di configurazione. L'unica differenza ora è la conservazione delle visualizzazioni personalizzate. Inoltre, ho ricontrollato il mio build.gradle, punta correttamente al mio file di configurazione (altrimenti, anche altre cose smetteranno di funzionare). – Sebastiano

+0

Ho aggiornato l'OP con la tua risposta e il motivo di questo comportamento. – Sebastiano