如何在混淆后获取 class 包,以便在 Android 上使用 Proguard 进行反射
How to get class package after obfuscation for use in reflection with Proguard on Android
目前 class 名称未被混淆。我需要找到特定 class 的混淆包以用于反射。有什么想法吗?
我可以想到两种方法:
从 /build/outputs/mapping.txt 中读取所需 class 的混淆包名称,然后将其写入文件(例如资产) 您可以在新的构建步骤中将其添加到 apk 中并在您的应用中读取。如果您不打算在您希望访问的那个之前(按字典顺序)添加新的 classes/packages,您甚至可以从 mapping.txt 中选择包名称并将其存储在某处的 String 字段中在应用程序中(但这是高度 unstable/undesirable)。
声明一个字段,其中包含对您希望通过反射访问的 class 的引用,在某个容易找到的地方(应用程序子 class 的名称和包是没有混淆,因为它们在清单中被引用,所以这将是一个很好的候选者)然后您只需使用该引用:
public class YourApplication extends Application {
//...
public static Class<?> yourReflectiveClass = YourReflectiveClass.class;
}
然后您访问该字段并根据需要使用它:
//...
Field[] appFields = YourApplication.class.getDeclaredFields();
Field classField = null;
for (Field f : appFields) {
if (f.getType().equals(Class.class) {
classField = f;
break;
}
}
if (classField != null) {
Object classInstance = classField.get(null);
if (classInstance instanceof Class) {
Class<?> yourReflectiveClass = (Class) classInstance;
// yourReflectiveClass.getPackage().getName()
}
}
您可能需要更改 proguard-rules.pro 以将您的新字段保留在混淆变体中。
另请注意,这种(至少部分)破坏了混淆的目的。
我找到了优雅的解决方案。我将字符串常量存储到具有所需 class 包值的环境变量中。我可以通过环境变量的静态字符串键访问任何需要的混淆数据。甚至 class 名字本身也被混淆了,我总是会得到需要的数据。很容易从应用程序中的任何模块访问此数据,因为它在环境变量中。
static {
System.setProperty(Const.NEEDED_PACKAGE, NeededClass.class.getPackage()).getName());
}
目前 class 名称未被混淆。我需要找到特定 class 的混淆包以用于反射。有什么想法吗?
我可以想到两种方法:
从
/build/outputs/mapping.txt 中读取所需 class 的混淆包名称,然后将其写入文件(例如资产) 您可以在新的构建步骤中将其添加到 apk 中并在您的应用中读取。如果您不打算在您希望访问的那个之前(按字典顺序)添加新的 classes/packages,您甚至可以从 mapping.txt 中选择包名称并将其存储在某处的 String 字段中在应用程序中(但这是高度 unstable/undesirable)。 声明一个字段,其中包含对您希望通过反射访问的 class 的引用,在某个容易找到的地方(应用程序子 class 的名称和包是没有混淆,因为它们在清单中被引用,所以这将是一个很好的候选者)然后您只需使用该引用:
public class YourApplication extends Application { //... public static Class<?> yourReflectiveClass = YourReflectiveClass.class; }
然后您访问该字段并根据需要使用它:
//...
Field[] appFields = YourApplication.class.getDeclaredFields();
Field classField = null;
for (Field f : appFields) {
if (f.getType().equals(Class.class) {
classField = f;
break;
}
}
if (classField != null) {
Object classInstance = classField.get(null);
if (classInstance instanceof Class) {
Class<?> yourReflectiveClass = (Class) classInstance;
// yourReflectiveClass.getPackage().getName()
}
}
您可能需要更改 proguard-rules.pro 以将您的新字段保留在混淆变体中。 另请注意,这种(至少部分)破坏了混淆的目的。
我找到了优雅的解决方案。我将字符串常量存储到具有所需 class 包值的环境变量中。我可以通过环境变量的静态字符串键访问任何需要的混淆数据。甚至 class 名字本身也被混淆了,我总是会得到需要的数据。很容易从应用程序中的任何模块访问此数据,因为它在环境变量中。
static {
System.setProperty(Const.NEEDED_PACKAGE, NeededClass.class.getPackage()).getName());
}