如何在混淆后获取类包以用于 Android 上的 Proguard 反射

问题描述

目前类名没有被混淆。我需要找到特定类的混淆包以用于反射。有什么想法吗?

解决方法

我可以想到两种方法:

  1. /build/outputs/mapping.txt 中读取所需类的混淆包名称,然后将其写入文件(例如资产),您可以将其添加到 apk 中,如新的构建步骤并阅读您的应用程序。如果您不打算在您希望访问的类/包之前(按字典顺序)添加新类/包,您甚至可以从 mapping.txt 中选择包名称并将其存储在应用程序某处的字符串字段中(但这是非常不稳定/不可取的)。

  2. 在容易找到的地方声明一个包含对您希望通过反射访问的类的引用的字段(Application 子类的名称和包没有被混淆,因为它们在清单中被引用,因此一个很好的候选人)然后你只需使用该参考:

    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 以将新字段保留在混淆变体中。 另请注意,这种方式(至少部分地)违背了混淆的目的。

,

我找到了优雅的解决方案。我将字符串常量存储到具有所需类包值的环境变量中。我可以通过环境变量的静态字符串键访问任何需要的混淆数据。甚至类名本身也被混淆了我会得到总是需要的数据。由于它位于环境变量中,因此可以轻松地从应用程序中的任何模块访问这些数据。

static {
    System.setProperty(Const.NEEDED_PACKAGE,NeededClass.class.getPackage()).getName());
}