Proguard的反射,使在android应用R类不再起作用 [英] Proguard makes reflection with the R class in android application no longer work

查看:315
本文介绍了Proguard的反射,使在android应用R类不再起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的项目启动以来的ProGuard我试图释放这个在谷歌播放。尽管ProGuard的-android.txt有

I have activated proguard in my project since I am trying to release this on Google Play. Even though proguard-android.txt has

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

}

这意味着它不应该混淆R.raw类,我需要,我发现,运行此code时

which means it should not obfuscate the R.raw class that I need, I find that when running this code

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

with path raw for example and a filename from there I get an ArrayIndexOutOfBoundsException at line

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

由于subClass.length为0。

since subClass.length is 0.

这件事工作,如果没有混淆,所以我想通这个问题是使用ProGuard就好了。

This thing works just fine if not obfuscating so I figured that the problem is with proguard.

我试着用不同的方法来使它不能混淆这样的第r类比赛:

I tried playing with different ways to make it not obfuscate the R classes like this:

-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 *;
}

和仍然无法正常工作。

我必须提到,我所有的code是在库(headwayEnt.Blackhole_Darksun)和我引用headwayEnt.Blackhole_Darksun_Full该库。基本上,我建立来自同一个code两个版本,一个完整的版本,一个是免费的演示。所有这一切都发生混淆的应用程序,而不是在引用的库(只是要清除)。

I must mention that all of my code is in a library (headwayEnt.Blackhole_Darksun) and that I reference that library in headwayEnt.Blackhole_Darksun_Full. Basically I am building two versions from the same code, one for full version and one for the free demo. All this obfuscation happens in the application, not in the referenced library (just to be clear).

推荐答案

这应该工作:

-keepattributes InnerClasses

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

InnerClasses 属性要获得什么类$ getDeclaredClasses()。该-keep选项是必要的,以保持相关类和字段,用自己原来的名称。

The InnerClasses attribute is necessary to get anything from Class$getDeclaredClasses(). The -keep options are necessary to keep the relevant classes and fields, with their original names.

这篇关于Proguard的反射,使在android应用R类不再起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆