Android中的Proguard和反射
Posted
技术标签:
【中文标题】Android中的Proguard和反射【英文标题】:Proguard and reflection in Android 【发布时间】:2011-05-25 17:34:07 【问题描述】:我刚刚使用了 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(...);
【问题讨论】:
我建议您编辑您的问题以仅包含该问题,然后自己回答该问题。两天左右后,您可以接受您的答案,其他用户将更好地理解您的解决方案。它还允许我们对您的答案和问题进行投票;) 【参考方案1】:已解决
对于遇到此问题的其他人,您需要将以下内容添加到 proguard.cnf
-keep public class * extends com.yoursite.android.yourappname.YourClassName
-keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName
public <init>(android.content.Context);
第一个 keep 告诉 proguard 不要混淆扩展 YourClassName 的类名
第二个说保持构造函数名称(<init>
表示构造函数)不混淆,它有一个参数Context
并扩展YourClassName
此外,对于在 XML 布局文件中使用 onClick 属性的 Android 开发人员,您还需要在 proguard.cnf 文件中添加函数的名称。
-keepclassmembers class *
public void myClickHandler(android.view.View);
这表示在所有类中保留名为 myClickHandler
的所有方法,并使用单个参数 View
。您可以通过使用上述的 extends 关键字来进一步限制这一点。
希望这会有所帮助。
【讨论】:
【参考方案2】:对于点击修复,您不必列出每个方法名称。你可以这样做:
-keepclassmembers class *
public void *(android.view.View);
查找所有以 View 作为参数的方法。
【讨论】:
【参考方案3】:因为编译过程会移除不使用的方法,所以即使在编译过程中使用反射调用构造方法也会被移除。
您可以在项目的usage.txt中看到编译过程中删除的方法。
所以你应该将构造函数方法保存在proguard文件中。
-keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName
public <init>(android.content.Context);
【讨论】:
以上是关于Android中的Proguard和反射的主要内容,如果未能解决你的问题,请参考以下文章
Android 安装包优化开启 ProGuard 混淆 ( 压缩 Shrink | 优化 Optimize | 混淆 Obfuscate | 预检 | 混淆文件编写 | 混淆前后对比 )
为啥我在使用 Proguard 时会从 Play Services lib 获得 ClassNotFoundException?