web-dev-qa-db-ja.com

Android

プロガードを使用したばかりですが、リフレクションを介してインスタンス化しようとしているクラスが機能していません。

インターフェースがあります

Algorithm

私はこのようなクラスを渡します

AlgorithmFactory.SomeClassThatExtendsAlgorithmImpl.class

クラスはこのようにインスタンス化されます

public ArrayList<Algorithm> getAlgorithms(Context cnx) {
ArrayList<Algorithm> list = new ArrayList<Algorithm>();

for(Class<? extends Algorithm> alg: algorithms) {

    try {
        Constructor<? extends Algorithm> c = alg.getConstructor(Context.class);
        list.add(c.newInstance(cnx));
    } catch (IllegalArgumentException e) {
        Log.e(TAG, "IllegalArgumentException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (InvocationTargetException e) {
        Log.e(TAG, "InvocationTargetException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (InstantiationException e) {
        Log.e(TAG, "InstantiationException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (IllegalAccessException e) {
        Log.e(TAG, "IllegalAccessException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (SecurityException e) {
        Log.e(TAG, "SecurityException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (NoSuchMethodException e) {
        Log.e(TAG, "NoSuchMethodException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    }
}
return list;
}

ここに私のproguard.cnfがあります

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends Android.app.Activity
-keep public class * extends Android.app.Application
-keep public class * extends Android.app.Service
-keep public class * extends Android.content.BroadcastReceiver
-keep public class * extends Android.content.ContentProvider
-keep public class com.Android.vending.licensing.ILicensingService


-keepclasseswithmembernames class * {
    native <methods>;
}

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

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

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(Java.lang.String);
}

-keep class * implements Android.os.Parcelable {
  public static final Android.os.Parcelable$Creator *;
}

-assumenosideeffects class Android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
    public static *** w(...);
    public static *** e(...);
}
34
jax

解決した

この問題を抱えている他の人のために、proguard.cnfに以下を追加する必要があります。

-keep public class * extends com.yoursite.Android.yourappname.YourClassName

-keepclassmembers class * extends com.yoursite.Android.yourappname.YourClassName{
 public <init>(Android.content.Context);
}

最初のキープは、YourClassNameを拡張するクラス名を難読化しないようにプロガードに指示します

2つ目は、コンストラクター名(<init>はコンストラクタを意味します)Contextの単一の引数を持ち、YourClassNameを拡張する難読化されていない

また、Android XMLレイアウトファイルでonClick属性を使用している開発者の場合も追加する必要があります。 proguard.cnfファイル内の関数の名前。

-keepclassmembers class * {
 public void myClickHandler(Android.view.View);
}

これは、すべてのクラスで単一の引数myClickHandlerを持つViewという名前のすべてのメソッドを保持することを示しています。上記のようにextendsキーワードを使用して、これをさらに制限することができます。

お役に立てれば。

60
jax

クリック時の修正では、各メソッド名をリストする必要はありません。できるよ:

-keepclassmembers class * {
   public void *(Android.view.View);
}

パラメータとしてビューを持つすべてのメソッドを検索します。

18
Amir Raminfar

コンパイルプロセスは使用されていないメソッドを削除するため、コンパイルプロセス中にリフレクションを使用して呼び出した場合でも、コンストラクターメソッドは削除されます。

プロジェクトのusage.txtで、コンパイルプロセス中に削除されるメソッドを確認できます。

したがって、コンストラクターメソッドをproguardファイルに保持する必要があります。

-keepclassmembers class * extends com.yoursite.Android.yourappname.YourClassName{
 public <init>(Android.content.Context);
}
0
Drown Coder