2012-12-17 5 views
6

Ho attivato proguard nel mio progetto poiché sto provando a rilasciarlo su Google Play. Anche se Proguard-android.txt haProguard effettua la riflessione con la classe R nell'applicazione Android non funziona più

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

}

il che significa che non deve offuscare la classe R.raw che ho bisogno, trovo che quando si esegue questo codice

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

con percorso raw per esempio e un nome file da lì ottengo un ArrayIndexOutOfBoundsException alla riga

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

poiché subClass.length è 0.

Questa cosa funziona bene se non è offuscante quindi ho pensato che il problema fosse con proguard.

Ho provato a giocare con diversi modi per farlo, non offuscare le classi R come questo:

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

e ancora non funziona.

Devo dire che tutto il mio codice è in una libreria (headwayEnt.Blackhole_Darksun) e che faccio riferimento a quella libreria in frontEnt.Blackhole_Darksun_Full. Fondamentalmente sto costruendo due versioni dello stesso codice, una per la versione completa e una per la demo gratuita. Tutta questa offuscazione avviene nell'applicazione, non nella libreria di riferimento (solo per essere chiari).

risposta

17

questo dovrebbe funzionare:

-keepattributes InnerClasses 

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

L'attributo InnerClasses è necessario per ottenere qualcosa da Class$getDeclaredClasses(). Le opzioni -keep sono necessarie per mantenere le classi e i campi rilevanti, con i loro nomi originali.

+0

Completamente dimenticato di questa domanda per così tanti mesi e ora ho dovuto offuscare quel pacchetto e mi hai salvato! Grazie! –

+0

Grazie Eric. Funziona bene per me! –

+0

Grazie mille. Mi hai salvato la vita ! :) – PAD