2015-05-22 5 views
9

Proguard rimuove i metodi sottoposti a override in una classe astratta come non utilizzati, anche se sono utilizzati nella classe padre. Ecco un'implementazione di riferimento che mostra il comportamentoProguard rimuove i metodi sottoposti a override in classe astratta come non utilizzati

public abstract class Animal { 
    Animal() { 
     born(); 
    } 

    abstract void born(); 
} 

public abstract class Human extends Animal { 
    @Override 
    void born() { 
     System.out.println("Human is born."); 
    } 
} 

La tenere attributi sono definiti come:

-keep public class test.Human { 
    public *; 
} 

Proguard rimuove le sovrascritti born() metodi nella classe umana come inutilizzato, anche se è utilizzato dal costruttore di classe animale. Il file di mapping risultante è

test.Animal -> test.a: 
    void born() -> a 
test.Human -> test.Human: 

Questo problema non esiste se la classe Human non è astratta. Se la classe è Human non astratta, il file di mapping risultante è

test.Animal -> test.a: 
    void born() -> a 
test.Human -> test.Human: 
    void born() -> a 

Come possiamo vedere, il metodo born() viene mantenuto in questo caso.

Si tratta di un bug in proguard? O c'è qualche impostazione di ottimizzazione che può fornire il comportamento desiderato?

Sto usando proguard con Android Studio.

+0

Esiste una classe concreta che estende Human? Se non c'è, potrebbe essere che si deduca che 'Human.born' non può mai essere eseguito. –

+0

@Devon_C_Miller Non esiste una classe concreta poiché fa parte della libreria. Lo stesso problema esiste se i costruttori vengono sostituiti da un altro metodo che viene mantenuto e visualizzato nella mappatura. – adwiv

risposta

1

Poiché il problema si manifesta solo quando queste classi sono parte di una libreria (e senza alcuna concreta attuazione all'interno della biblioteca), ho preso la via più semplice e ho aggiunto -dontshrink per conservare (con occultamento) tutte le classi e i metodi.

Nella maggior parte dei casi; la classe e il restringimento del metodo non devono essere eseguiti quando si rilascia una libreria.

Ancora credo che sia un errore nel grafico di utilizzo ignorare le implementazioni del metodo sottoposto a override. Ho registrato un errore nel tracker dei bug di proguard. https://sourceforge.net/p/proguard/bugs/574/

2

Si configura ProGuard per mantenere pubblico metodi, mentre born() è pacchetto privato. La tua configurazione dovrebbe essere piuttosto come questa.

-keep public class test.Human { 
    <methods>; 
} 

Conserverà tutti i metodi privati ​​(predefiniti) di classe umana.

Se si desidera mantenere i metodi, ma ancora consentire di offuscamento per loro, si può usare qualcosa di simile:

-keep, allowobfuscation public class test.Human { 
    <methods>; 
} 
+0

il problema qui non riguarda il 'mantenere i metodi' ma il proguard che non riconosce il metodo sottoposto a override come usato e li riduce portando a un file di classe incompleto. Ciò accade solo quando creo una libreria poiché il problema si manifesta solo in una classe astratta. Il tuo suggerimento funziona ma è piuttosto come -noshrink che non voglio usare. – adwiv

+0

Tuttavia il tuo suggerimento mi dà un'idea di mantenere con l'offuscamento tutti i metodi sovrascritti di una classe astratta nella libreria che ha senso. Cosa dovremmo usare per questo? – adwiv