Android中的前进和反射
-
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);
}
第一个保留告诉Proguard不要混淆扩展您的classname的类名称
第二个说要保留构造函数(<init>
含义构造函数)未敲打,该论点是一个单一的论点 Context
并扩展 YourClassName
此外,对于使用的Android开发人员 XML布局文件中的onClick属性文件 您还需要在proguard.cnf文件中添加函数的名称。
-keepclassmembers class * {
public void myClickHandler(android.view.View);
}
这说明所有方法命名 myClickHandler
有一个论点 View
在所有课程中。您可以通过使用上面的扩展关键字来进一步限制这一点。
希望这可以帮助。
其他提示
对于单击“修复”,您不必列出每个方法名称。你可以做:
-keepclassmembers class * {
public void *(android.view.View);
}
找到所有具有参数的方法。
因为编译过程将删除未使用的方法,因此即使您在编译过程中使用反射来调用,构造方法也将被删除。
您可以在项目中的useage.txt中查看在编译过程中被删除的方法。
因此,您应该将构造函数方法保留在Proguard文件中。
-keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName{
public <init>(android.content.Context);
}
不隶属于 StackOverflow