【发布时间】:2014-11-18 12:46:21
【问题描述】:
我叫 Matthew,在使用 ProGuard 后,我在 Android 上的反射遇到了一些麻烦。
我在 libgdx 中编写游戏,我需要动态获取 String,我有这样的东西:
package com.PACKAGE;
public class CLASS extends ANOTHER_CLASS{
(...)
private static void load(String fieldName) {
Field field;
String fileName;
try {
field = SOME_CLASS.class.getField(fieldName);
fileName = (String) field.get(null);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
SOME_CLASS.SOME_METHOD.load(fileName);
}
(...)
private STH get(String fieldName) {
Field field;
String fileName;
try {
field = SOME_CLASS.class.getField(fieldName);
fileName = (String) field.get(null);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return SOME_CLASS.SOME_METHOD.get(fileName);
}
(...)
}
在我导出发布 apk(编译正常)并运行游戏后,我得到 NoSuchFieldException:
java.lang.RuntimeException: java.lang.NoSuchFieldException: FIELD_NAME
我需要在proguard-project.txt 中添加什么来处理这个问题?这不起作用,我不知道该怎么办。
-keepclassmembers class com.PACKAGE.CLASS {
String fileName;
}
类看起来像:
package com.ANOTHER_PACKAGE;
public class SOME_CLASS {
public static final String fieldName1 = "string I want";
public static final String fieldName2 = "string I want";
public static final String fieldName3 = "string I want";
}
更新:
感谢@Selvin,答案是
-keepclassmembers class ANOTHER_PACKAGE.SOME_CLASS {
public static final <fields>;
}
在project-proguard.txt。现在它完美地工作了:)
【问题讨论】:
-
首先为什么需要对此进行反思。第二,不应该是
-keepclassmembers class com.PACKAGE.SOME_CLASS -
我需要反思以避免编写一堆代码,但也许这不是一个好主意。 SOME_CLASS 在另一个包中,我需要获取更多字符串字段,所以我需要编写所有可以通过反射使用的字符串? -keepclassmembers class com.ANOTHER_PACKAGE.CLASS { String fileName1;字符串文件名2;字符串文件名3; }
-
所以 SOME_CLASS 来自 libgdx ?文件名是静态的吗?你知道
field.get(null)是给静态成员的吗? (我知道错误不在这里但是)您需要传递 SOME_CLASS 的实例而不是 null 来获取非静态字段... -
不是来自,但是当你用干净的 Java 编写时,我在“核心”部分使用它,而不是在“Android”部分。是的,我尝试得到的所有字符串都是静态的。
标签: java android reflection libgdx proguard