2016-09-27 2 views
12

匿名クラス内で匿名クラスを宣言すると、Proguardが動作しないという問題があります。これは、基本的な例では次のようになります。ProguardはJavaのAnonymousクラスのAnonymousクラスを削除します

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

グラデルビルドスクリプトのプロガードが実行中です。私は匿名クラスのProGuardのの1「レベル」を持っているコードがエラーなしで仕上げている変更する場合

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

:今、私は次のエラーを取得します。これは動作します:

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 
     } 
    } 
    } 
} 

プロジェクトはアンドロイドプロジェクトですが、問題ではないと私が知っている限りです。

私はの異なる種類のすべてを試しましたが、Class1のルールは動作しませんでした。これはProguardによってサポートされていないのですか、それを動作させるためにルールを追加する必要がありますか?

UPDATE 1:

としてインタフェースは匿名クラスのために使用した場合の構造を要求しました。 次のようにClass2ためのインタフェースが定義されている:

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

Class3ためのインターフェースが若干異なっている。

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

注:それらはによって提供されているので、私はインターフェイスのレイアウトを変更することはできませんアンドロイド。

+1

Class2は、いくつかのクラス(Fooなど)を拡張する必要があります。あなたはこのようないくつかの条項を保持することができます。 -keep class * extends Foo {public void function2;} – kujeensiti

+0

Class2はインターフェイスを実装します。これはインターフェースの内部インターフェース(これはAndroidからのものです)として定義されます。私は試しました: '-keep class * extends package.OuterInterface {*; } 'と' -keep class * extends package.OuterInterface.InnerInterface {*; } 'と' -keep class * extends package.OuterInterface $ InnerInterface {*; } '。私は '-keepattributes InnerClasses'も起動しました。残念ながら運はありません。 –

+1

ネスティングを理解するために、インターフェイスとその使用方法の正確な構造を共有してください。 (正確な完全修飾名は期待していません) – kujeensiti

答えて

1

function1()、function2()、function3()の上に@Keepアノテーションを使用できます。

public class Class1 { 
    @Keep 
    public void function1(){ 
    new Class2(){ 
     @Keep 
     @Override 
     public void function2(){ 
      new Class3(){ 
      @Keep 
      @Override 
      public void function3(){ 
       // do something 
      } 
      } 
     } 
    } 
    } 
} 
関連する問題