2016-09-27 5 views
12

Ich habe ein Problem, dass Proguard nicht funktioniert, wenn Sie eine anonyme Klasse in einer anonymen Klasse deklarieren. Dies ist, wie es in einem einfachen Beispiel aussieht:Proguard entfernt anonyme Klasse in anonymer Klasse in Java

public class Class1 { 
    public void function1(){ 
    new Class2(){ 
     @Override 
     public void function2(){ 
      new Class3(){ 
      @Override 
      public void function3(){ 
       // do something 
      } 
      } 
     } 
    } 
    } 
} 

Während eines gradle Build-Skript proguard ausgeführt wird. Jetzt bekomme ich folgende Fehlermeldung:

my.package.Class1$2$1: can't find enclosing method 'void function2()' in program class my.package.Class1$2 

Wenn ich den Code ändern zu müssen nur 1 „level“ von anonymen Klassen proguard ohne Fehler beenden. Das funktioniert:

public class Class1 { 
    public void function1(){ 
     Class3 class3Instance = new Class3(){ 
      @Override 
      public void function3(){ 
       // do something 
      } 
     } 
     new Class2(){ 
     @Override 
     public void function2(){ 
      //do something with class3Instance 
     } 
    } 
    } 
} 

Das Projekt ist ein Android-Projekt, obwohl, soweit ich weiß, sollte das keine Rolle spielen.

Ich versuchte alle anderen Art von -keep Regeln für Class1, aber nichts hat funktioniert. Wird dies nicht von Proguard unterstützt oder muss ich eine Regel hinzufügen, damit es funktioniert?

UPDATE 1:

Wie gewünscht, die Struktur, wenn die Schnittstelle für die anonymen Klassen verwendet. Die Schnittstelle für Class2 ist wie folgt definiert:

public class Class2IntefaceEnclosingClass { 
    public interface Class2 { 
     void function2(); 
    } 
} 

Die Schnittstelle für Class3 ist etwas anders:

public interface Class3IntefaceEnclosingInterface { 
    interface Class3 { 
     void function3(); 
    } 
} 

Hinweis: Ich kann das Layout der Schnittstellen ändern, da sie durch vorgesehen sind Android.

+1

Class2 muss eine Klasse erweitern (sagen Foo). Du kannst eine Sache wie diese behalten. -keep class * erweitert Foo {public void function2;} – kujeensiti

+0

Class2 implementiert eine Schnittstelle. Was wiederum als innere Schnittstelle einer Schnittstelle definiert ist (es kommt von Android). Ich habe versucht: '-keep class * extends package.OuterInterface {*; } 'und' -keep class * extends package.OuterInterface.InnerInterface {*; } 'und' -keep class * extends package.OuterInterface $ InnerInterface {*; } '. Ich habe auch '-keeptributes InnerClasses' aktiviert. Leider kein Glück. –

+1

Könnten Sie bitte die genaue Struktur der Schnittstelle und ihre Verwendung teilen, um die Verschachtelung zu verstehen. (Genaue voll qualifizierte Namen werden nicht erwartet) – kujeensiti

Antwort

1

Sie können versuchen, @Keep Annotation über Funktion1(), Funktion2() und Funktion3() zu verwenden.

public class Class1 { 
    @Keep 
    public void function1(){ 
    new Class2(){ 
     @Keep 
     @Override 
     public void function2(){ 
      new Class3(){ 
      @Keep 
      @Override 
      public void function3(){ 
       // do something 
      } 
      } 
     } 
    } 
    } 
} 
Verwandte Themen