java - Proguard 使 android 应用程序中的 R 类反射不再起作用

标签 java android release proguard

我已经在我的项目中激活了混淆器,因为我正试图在 Google Play 上发布它。即使 proguard-android.txt 有

-keepclassmembers class **.R$* {
public static <fields>;

这意味着它不应该混淆我需要的 R.raw 类,我发现在运行这段代码时

import headwayEnt.Blackhole_Darksun.R;

private static final String RES_PATH = "headwayEnt.Blackhole_Darksun.R";

public static int getFileHandle(String fileName, String path) {
    String fullPath = RES_PATH + '$' + path;
    if (subClass == null) {
        Class<headwayEnt.Blackhole_Darksun.R> c = null;     
        try {
            c = (Class<R>)Class.forName(RES_PATH);
        } catch(ClassNotFoundException e) {
            e.printStackTrace();
        } catch(ClassCastException e) {
            e.printStackTrace();
        }
        subClass = c.getDeclaredClasses();
    }
    int fileHandle = 0;
    try {
        int i = 0;
        System.out.println("fullPath: " + fullPath + " subclass len: " +
                subClass.length);
        for (; i < subClass.length; ++i) {
            String name = subClass[i].getName();
            if (subClass[i].getName().equals(fullPath)) {
                break;
            }
        }
        System.out.println("found i: " + i);
        Field[] f = subClass[i].getDeclaredFields();
        for (i = 0; i < f.length; ++i) {
            if (f[i].getName().equals(fileName)) {
                break;
            }
        }

        try {
            fileHandle = f[i].getInt(null);
        } catch(IllegalAccessException e) {

        }
    } catch (RuntimeException e) {
        System.out.println("Could not find filename: " + fileName + 
                " with path: " + path);
        throw e;
    }
    return fileHandle;
}

例如,使用原始路径和那里的文件名,我在第 行得到一个 ArrayIndexOutOfBoundsException

Field[] f = subClass[i].getDeclaredFields();

因为 subClass.length 为 0。

如果不混淆的话,这个东西工作得很好,所以我认为问题出在 proguard 上。

我尝试了不同的方法来避免像这样混淆 R 类:

-keep public class headwayEnt.HotshotEngine.Resource.ENG_Resource { *; }
-keep class headwayEnt.HotshotEngine.** { *; }
-keep class **.R$*
-keep public class headwayEnt.Blackhole_Darksun.R { *; }
-keep public class headwayEnt.Blackhole_Darksun_Full.R { *; }
-repackageclasses ''
-keep public class **.R {
  public *;
}
-keep public class **.R$* {
  public *;
}

还是不行。

我必须提到,我的所有代码都在库 (headwayEnt.Blackhole_Darksun) 中,并且我在 headwayEnt.Blackhole_Darksun_Full 中引用了该库。基本上我是用相同的代码构建两个版本,一个用于完整版,一个用于免费演示。所有这些混淆都发生在应用程序中,而不是在引用的库中(只是为了清楚起见)。

最佳答案

这应该有效:

-keepattributes InnerClasses

-keep class **.R
-keep class **.R$* {
    <fields>;
}

InnerClasses 属性是从 Class$getDeclaredClasses() 获取任何内容所必需的。 -keep 选项对于保留相关类和字段及其原始名称是必需的。

关于java - Proguard 使 android 应用程序中的 R 类反射不再起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13923815/

相关文章:

java - Spring Data Mongodb - 用于收集不同类型的存储库

java - 如何在我的应用程序中附加我使用相机拍摄的照片?

android - 应用程序无法在我的手机中启动,但是调试器/logcat/控制台根本没有显示任何错误

flutter - 失败: Build failed with an exception (Shared preference and gradle wrapper properties)

flutter - 如何清理 Flutter/bin 文件夹缓存

java - Jenkins 发布作业与构建作业

java - 你曾经在任何项目中使用过 PhantomReference 吗?

java - 如何将 JOptionPane.showOptionDialog 的默认选择更改为 default_close_operation

java - JSONObject keySet() 函数不存在吗?

java - 使用 Spring 4 和 AngularJS 摆脱第一个 View Controller