我发现似乎有两种一般的解决方案:
这些解决方案仅适用于同一项目中的调用 - 客户端代码(在另一个项目中)可能不使用反射API来访问非公共API方法。
在2的情况下,它也仅在Reflection API与编译时已知的字符串一起使用时才有效(私有方法测试?)。在这些情况下,dp4j还提供了一种在混淆后注入反射代码的解决方案。
阅读Proguard FAQ我想知道2,否则它总是有效:
问:粗体语句是什么意思?有什么例子吗?ProGuard会自动处理 像。这样的结构 Class.forName(“SomeClass”)和 SomeClass.class。引用 课程在萎缩中得以保留 阶段,字符串参数是 在混淆中正确替换 相。
使用变量字符串参数,通常无法确定 他们可能的价值观。
答案 0 :(得分:2)
使用变量字符串参数时,通常无法确定其可能的值。
public Class loadIt(String clsName) throws ClassNotFoundException {
return Class.forName(clsName);
}
基本上如果你将非常量字符串传递给Class.forName,通常没有办法让proguard或任何混淆工具弄清楚你在说什么类,因此不能自动为你调整代码。 / p>
答案 1 :(得分:2)
Zelix KlassMaster Java混淆器可以自动处理所有Reflection API调用。它有一个名为AutoReflection的函数,它使用“加密旧名称”到“混淆名称”查找表。
但是,它只能用于同一混淆项目中的调用。
请参阅http://www.zelix.com/klassmaster/docs/tutorials/autoReflectionTutorial.html。
答案 2 :(得分:1)
这意味着:
String className;
if (Math.random() <= 0.5) className = "ca.simpatico.Foo";
else className = "ca.simpatico.Bar";
Class cl = Class.forName(className);
混淆后无效。 ProGuard没有进行足够深入的数据流分析,无法看到加载的类名来自这两个字符串文字。
真的,你唯一合理的选择是决定哪些类,接口和方法应该通过反射访问,然后不要混淆那些。您正在为客户端有效地定义一种奇怪的API - 只能以反射方式访问它。