2012-12-17 9 views
6

Ich habe in meinem Projekt proguard aktiviert, da ich versuche, dies bei Google Play zu veröffentlichen. Obwohl proguard-android.txt hatProguard macht Reflektion mit der R-Klasse in Android-Anwendung nicht mehr funktioniert

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

}

was bedeutet, sollte es nicht die R.raw Klasse verschleiern, die ich brauche, finde ich, dass bei der Ausführung von 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; 
} 

mit Pfad zum Beispiel und einen Dateinamen von dort bekomme ich eine ArrayIndexOutOfBoundsException in Zeile

seit subClass.length ist 0.

Diese Sache funktioniert gut, wenn nicht verschleiern, so dachte ich, dass das Problem mit Proguard ist.

habe ich versucht, mit verschiedenen Möglichkeiten zu spielen, die R-Klassen wie diese machen es nicht verschleiern:

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

und immer noch nicht funktioniert.

Ich muss erwähnen, dass mein gesamter Code in einer Bibliothek ist (headwayEnt.Blackhole_Darksun) und dass ich diese Bibliothek in headwayEnt.Blackhole_Darksun_Full referenziere. Im Grunde baue ich zwei Versionen aus dem gleichen Code, einen für die Vollversion und einen für die kostenlose Demo. All diese Verschleierung geschieht in der Anwendung, nicht in der referenzierten Bibliothek (nur um klar zu sein).

Antwort

17

sollte diese Arbeit:

-keepattributes InnerClasses 

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

Das InnerClasses Attribut ist notwendig, alles von Class$getDeclaredClasses() zu bekommen. Die Optionen -keep sind notwendig, um die relevanten Klassen und Felder mit ihren ursprünglichen Namen zu behalten.

+0

Ich habe diese Frage für so viele Monate komplett vergessen und musste nun dieses Paket verschleiern und du hast mich gerettet! Vielen Dank! –

+0

Danke Eric. Funktioniert gut für mich! –

+0

Vielen Dank. Du hast mein Leben gerettet ! :) – PAD

Verwandte Themen