根据this question中@AlexWein的建议并查看ProGuard Troubleshooting,我在SherlockFragment中有以下内容:
Class<?> c = Class.forName("co.uk.MyApp.pdf.MyData");
Method main = c.getDeclaredMethod("pdfsleep", Report_Holder.class);
Report_Holder paramsh = null;
paramsh = SRH;
main.invoke(null, (Object)paramsh);
&#34; co.uk.MyApp.pdf.Data&#34;构造函数是:
public class MyData {
public static void pdfsleep(Report_Holder args) {
...
}
}
Proguard的设置如下:
-keepnames class co.uk.MyApp.classes.Report_Holder
-keepclassmembers class co.uk.MyApp.pdf.Data { public static void pdfsleep(Report_Holder); }
-keepnames class co.uk.MyApp.DataActivity
但我仍然得到NoSuchMethodException:
05/23/13 12:14:28 GMT+01:00 ERROR AsyncTask #2 - java.lang.NoSuchMethodException: pdfsleep [class co.uk.MyApp.classes.Report_Holder]
at java.lang.Class.getConstructorOrMethod(Class.java:460)
at java.lang.Class.getDeclaredMethod(Class.java:685)
at co.uk.MyApp.fy.a(Unknown Source)
at co.uk.MyApp.fy.doInBackground(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
我错过了什么?
更新
我已将Proguard行更改为:
-keepattributes Signature
-keepnames class co.uk.MyApp.classes.Report_Holder
-keepclasseswithmembers class co.uk.MyApp.DataActivity
-keepclasseswithmembers class co.uk.MyApp.pdf.Data { void pdfsleep(Report_Holder); }
我仍然得到错误。
查看映射文件,我认为我看到了导致问题的原因:
co.uk.MyApp.classes.Report_Holder -> co.uk.MyApp.classes.Report_Holder:
co.uk.MyApp.DataActivity -> co.uk.MyApp.DataActivity:
java.util.ArrayList arrDataItems -> a
co.uk.MyApp.classes.Report_Holder SRH -> b
看起来Proguard保留了对co.uk.MyApp.classes.Report_Holder的引用,但是当它作为co.uk.MyApp.DataActivity的子代引用时它正在混淆。
我尝试过不同的方法来保留co.uk.MyApp.DataActivity,试图让它停止混淆co.uk.MyApp.classes.Report_Holder,但无法正确识别语法。有什么建议吗?
更新2
我已经按照Eric Lafortune的建议更新了一些代码和ProGuard配置文件(顺便说一下,我现在正在显示正确的包/类名):
在co.uk.FibroApp.SleepDataActivity
中Class<?> c = Class.forName("co.uk.FibroApp.pdf.SleepData");
Method main = c.getDeclaredMethod("pdfsleep", co.uk.FibroApp.classes.SleepReport_Holder.class);
SleepReport_Holder paramsh = SRH;
co.uk.FibroApp.pdf.SleepData是:
public class SleepData {
public static void pdfsleep(co.uk.FibroApp.classes.SleepReport_Holder args) {
...
}
}
完整的ProGuard配置是:
-keepattributes Signature
-keep class co.uk.FibroApp.classes.SleepReport_Holder
-keep class co.uk.FibroApp.pdf.SleepData
-keepclassmembers class co.uk.FibroApp.pdf.SleepData {
public static void pdfsleep(co.uk.FibroApp.classes.SleepReport_Holder);
}
# do not obfuscate the classes from droidtext but shrink them
-keep,allowshrinking class harmony.java.awt.** { *; }
-keep,allowshrinking class org.apache.harmony.** { *; }
-keep,allowshrinking class org.bouncycastle.** { *; }
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
-keepattributes *Annotation*
完整的错误日志是:
05/24/13 08:25:52 WEST ERROR AsyncTask #2 - java.lang.NoSuchMethodException: sleeppdf [class co.uk.FibroApp.classes.SleepReport_Holder]
at java.lang.Class.getConstructorOrMethod(Class.java:460)
at java.lang.Class.getDeclaredMethod(Class.java:685)
at co.uk.FibroApp.fy.a(Unknown Source)
at co.uk.FibroApp.fy.doInBackground(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
答案 0 :(得分:1)
<强>解决!强>
我将这些行添加到ProGuard配置文件中:
-keep class co.uk.FibroApp.pdf.SleepDataActivity
-keep class co.uk.FibroApp.pdf.SleepMainActivity
我添加了SleepDataActivity,因为这是保存与pdfsleep联系的异步任务的类。
我添加了SleepMainActivity,因为SleepDataActivity在技术上是TabSwipe Activity中的片段,SleepMainActivity是这些标签的父级。
现在在mapping.txt中提到了我会接受Eric Lafortune的回答作为这个问题的答案,因为他对'-keepclassmembers'的语法不是我自己应该得到的,也是因为我在之前的一个问题中接受了AlexWien的回答我到了这个阶段。
谢谢你们两位,你们已经保存了我的发布日期!
答案 1 :(得分:0)
您的一个问题可能是在模糊规则中指定了Report_Holder
,
但排除方法使用SleepReport_Holder
。
我使用这个规则 它是在ant proguard扩展中,但您可以轻松地将其转换为其他规则描述系统:
<keepclasseswithmembers name="co.uk.MyApp.pdf.MyData" access="public">
<method access="public static" type="void" name="pdfsleep" parameters="co.uk.MyApp.classes.SleepReport_Holder" />
</keepclasseswithmembers>
另外vor java&gt; 1.5 使用规则
-keepattributes Signature
否则集合和泛型将无效
答案 2 :(得分:0)
您的代码通过反射访问方法。堆栈跟踪表明ProGuard已删除或重命名它。因此,您应该使用几乎直接复制代码标题的行来保留它:
-keepclassmembers class co.uk.MyApp.pdf.MyData {
public static void pdfsleep(co.uk.MyApp.classes.Report_Holder);
}
ProGuard识别Class.forName构造并已保留类MyData。为了更好地衡量,您可以确保ProGuard不会删除类Report_Holder(如果该类恰好未使用,而不是作为参数类型):
-keep,allowobfuscation class co.uk.MyApp.classes.Report_Holder
注意:
ProGuard文档解释了各种保养选项之间的差异。如果你不确定,只需使用-keep。 (CFR)。用法&gt; Overview of Keep Options
您可能在控制台日志中看到警告,必须使用其完全限定名称指定Report_Holder。