AndroidのProguardとReflection
-
10-10-2019 - |
質問
Proguardを使用しましたが、リフレクションを介してインスタンス化しようとしているクラスは機能していません。
インターフェイスがあります
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(...);
}
解決
解決した
この問題を抱えている他の人のために、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を拡張するクラス名を難読化しないようにProguardに伝えます
2番目のものは、コンストラクター名を保持するように言います(<init>
and constructor)は、次の1つの議論を持つ未吸引型 Context
そして拡張します YourClassName
さらに、を使用しているAndroid開発者向け you xmlレイアウトファイルのonclick属性 また、proguard.cnfファイルに関数の名前を追加する必要があります。
-keepclassmembers class * {
public void myClickHandler(android.view.View);
}
これには、すべてのメソッドが名前が付けられていると書かれています myClickHandler
単一の引数で View
すべてのクラスで。上記のように拡張キーワードを使用して、これをさらに制約することができます。
お役に立てれば。
他のヒント
修正]をクリックすると、各メソッド名をリストする必要はありません。できるよ:
-keepclassmembers class * {
public void *(android.view.View);
}
パラメーターとしてビューを持つすべてのメソッドを見つけます。
コンパイルプロセスは使用されていないメソッドを削除するため、コンパイルプロセス中にリフレクションを使用して呼び出す場合でも、コンストラクターメソッドが削除されます。
プロジェクトのusage.txtで、編集プロセス中に削除される方法を見ることができます。
したがって、コンストラクターメソッドをProguardファイルに保持する必要があります。
-keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName{
public <init>(android.content.Context);
}