7

これを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 なので。

このことは、難読化されていなければ問題なく機能するため、問題はプロガードにあると考えました。

次のように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 でそのライブラリを参照していることに言及する必要があります。基本的に、私は同じコードから 2 つのバージョンを作成しています。1 つはフル バージョン用で、もう 1 つは無料のデモ用です。この難読化はすべて、参照先のライブラリではなく、アプリケーションで行われます (明確にするため)。

4

1 に答える 1

22

これは機能するはずです:

-keepattributes InnerClasses

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

このInnerClasses属性は、から何かを取得するために必要Class$getDeclaredClasses()です。-keepオプションは、関連するクラスとフィールドを元の名前で保持するために必要です。

于 2012-12-20T00:23:45.330 に答える