2012-08-28 26 views
19

Estoy usando simplexml en mi proyecto de Android, y todo funciona bien hasta que ofuscar el código. A continuación, los errores de comenzar a verter enOfuscación Proguard está rompiendo simplexml

parte del XML es el siguiente:.

<categories success="true"> 
    <category id="102" caption="Magazin" parent="0" num_mags="114" > 
    <category id="15" caption="Kunst" parent="102" num_mags="13" > 
     <category id="17" caption="Design" parent="15" num_mags="10" ></category> 
     <category id="18" caption="Haute+Couture" parent="15" num_mags="2" > 
... 

Tengo dos clases: CategoryItemList:

@Root(name = "categories") 
public class CategoryItemList { 

    private final List<CategoryItem> mCategoryItems; 
    /** 
    * Create a new category items list. 
    * 
    * @param categoryItems the list of category items 
    */ 
    public CategoryItemList(@ElementList(name = "category", inline = true) final List<CategoryItem> categoryItems) { 
     mCategoryItems = categoryItems; 
    } 
    @ElementList(name = "category", inline = true) 
    public List<CategoryItem> getCategoryItems() { 
     return mCategoryItems; 
    } 
} 

y CategoryItem:

@Root(name = "category") 
public class CategoryItem { 
    private final int mId; 
    private final String mCaption; 
    private final int mParent; 
    private final int mNumberOfMagazines; 
    private final ArrayList<CategoryItem> mSubCategoryItems; 
    /** 
    * Creating a new category item. 
    * 
    * @param id the category id 
    * @param caption the name of category 
    * @param parent the parent category 
    * @param numMags the number of magazines from that category 
    */ 
    public CategoryItem(@Attribute(name = "id") final int id, 
         @Attribute(name = "caption") final String caption, 
         @Attribute(name = "parent") final int parent, 
         @Attribute(name = "num_mags") final int numMags, 
         @ElementList(name = "category", inline = true, required = false) final ArrayList<CategoryItem> subCategoryItems) { 
     mId = id; 
     mCaption = caption; 
     mParent = parent; 
     mNumberOfMagazines = numMags; 
     mSubCategoryItems = subCategoryItems; 
    } 

    @Attribute(name = "id") 
    public int getId() { 
     return mId; 
    } 

    @Attribute(name = "caption") 
    public String getCaption() { 
     String categoryName = null; 

     try { 
      categoryName = URLDecoder.decode(mCaption, "UTF-8"); 
     } catch (final UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 
     return categoryName; 
    } 

    @Attribute(name = "parent") 
    public int getParentId() { 
     return mParent; 
    } 

    @Attribute(name = "num_mags") 
    public int getNumbersOfMagazines() { 
     return mNumberOfMagazines; 
    } 

    @ElementList(name = "category", inline = true, required = false) 
    public ArrayList<CategoryItem> getSubCategory() { 
     return mSubCategoryItems; 
    } 
} 

Ahora, cuando ofusque el código, si lo dejo fuera "-keepattributes Anotación "Obtengo una PersistenceException: Constructor no coincide para la clase.

Si lo incluyo, aparece la excepción "No se puede determinar el tipo genérico para el parámetro 1 del constructor", todo esto en tiempo de ejecución.
Como puede ver, los nombres están ahí e intenté -mantener toda la clase contendiéndolos, todo fue en vano.

¿Cómo puedo configurar Proguard para que funcione con simplexml?

EDIT: Mi archivo proguard.cfg es el siguiente: (es un poco rellena con todas las cosas que he intentado, pero esta es la versión actual)

-dontusemixedcaseclassnames 
-dontskipnonpubliclibraryclasses 
-dontpreverify 
-verbose 
-printseeds 
-dontoptimize 
-keepattributes *Annotation* 
-keepattributes EnclosingMethod 

-libraryjars <java.home>/lib/rt.jar (javax/xml/stream/**) 

-keep public class * extends android.app.Activity 
-keep public class * extends android.app.Application 
-keep public class * extends android.app.Service 
-keep public class * extends android.content.BroadcastReceiver 
-keep public class * extends android.content.ContentProvider 
-keep public class * extends android.app.backup.BackupAgentHelper 
-keep public class * extends android.preference.Preference 

-keepclasseswithmembers class * { 
    native <methods>; 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

-keepclassmembers enum * { 
    public static **[] values(); 
    public static ** valueOf(java.lang.String); 
} 

-keep class * implements android.os.Parcelable { 
    public static final android.os.Parcelable$Creator *; 
} 

-dontwarn android.support.**,de.greenrobot.**,org.simpleframework.xml.** 
-keep class com.crittercism.**{ *; } 
-keepclassmembernames class com.crittercism.**{ *; } 
-keepclasseswithmembers class com.crittercism.**{ *; } 

-keep class org.simpleframework.**{ *; } 
-keepclassmembernames class org.simpleframework.**{ *; } 
-keepclasseswithmembers class org.simpleframework.**{ *; } 

-keep class crittercism.android.** 
-keepclassmembers public class com.crittercism.*{ *;} 

-keep public class database.** { 
    public static <fields>; 
} 

-keep class android.support.** 
-keepclasseswithmembers class android.support.** { *;} 

-keep class org.simpleframeork.** 
-keepclasseswithmembers class org.simpleframeork.** { *;} 

-keep class javax.** 
-keepclasseswithmembers class javax.** { *;} 

-keep class com.test.category.** 
-keepclassmembernames class com.test.category.** { *; } 
-keepclasseswithmembers class com.test.category.** { *;} 

-keep class com.test.download.** 
-keepclassmembernames class com.test.download.** { *; } 
-keepclasseswithmembers class com.test.download.** { *;} 

-keep class org.simpleframework.**{ *; } 
-keep class org.simpleframework.xml.**{ *; } 
-keep class org.simpleframework.xml.core.**{ *; } 
-keep class org.simpleframework.xml.util.**{ *; } 
-keep class org.simpleframework.xml.stream.**{ *; } 

-keepclassmembers class * implements java.io.Serializable { 
    private static final java.io.ObjectStreamField[] serialPersistentFields; 
    private void writeObject(java.io.ObjectOutputStream); 
    private void readObject(java.io.ObjectInputStream); 
    java.lang.Object writeReplace(); 
    java.lang.Object readResolve(); 
} 
+1

publique su proguard.cfg –

Respuesta

2

clic derecho sobre el proyecto en Eclipse . Ve a Android -> ejecuta Lint.

Lint tiene la capacidad de verificar las configuraciones erróneas de proguard y puede retomar y explicar su error.

+0

I fo y una advertencia de Proguard, pero eliminarlo no ayudó con mi problema. – Janusz

6

Ya has descubierto que mantener una anotación es una buena idea. También puede intentar agregar un parámetro de tipo a la anotación @ElementList. Aparentemente hay un problema con el borrado de tipo genérico y simplexml necesita sugerencias adicionales sobre el tipo de elementos en la lista

También puede jugar con -keepattributes Firma, * Anotación *: atributo

la "firma" es necesaria para poder acceder a genéricos tipos al compilar en el JDK 5.0 y superior.

+0

Al principio me costó entender lo que quería decir, pero ahora entiendo completamente y mi problema fue resuelto por esta respuesta. –

+0

Funciona de verdad. Al final, mi declaración se ve así: '@ElementList (inline = true, type = Myclass.class)' –

4

Los problemas cuando se utiliza la biblioteca SimpleXML y ofuscar el código son los siguientes:

  1. Hay que mantener la "Anotaciones" y "firmas" de sus entidades

    @Attribute (name = "retcode", required = true) Cadena privada _retcode;

  2. usted tiene que mantener la biblioteca SimpleXML

  3. Tienes que evitar que ciertos bloques de código sea eliminar, por ejemplo, si no se utiliza el constructor de una entidad, Proguard lo eliminará, pero ese método puede ser internamente utilizada por la Biblioteca simple XML

El archivo proguard.cfg puede ser algo como esto:

# The following line may be different 
-libraryjars <java.home>/lib/rt.jar(java/**,javax/**) 

-optimizationpasses 5 
-dontusemixedcaseclassnames 
-dontskipnonpubliclibraryclasses 
-dontpreverify 
-verbose 
# (3)Not remove unused code 
-dontshrink 

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 

-keep public class * extends android.app.Activity 
-keep public class * extends android.app.Application 
-keep public class * extends android.app.Service 
-keep public class * extends android.content.BroadcastReceiver 
-keep public class * extends android.content.ContentProvider 
-keep public class * extends android.app.backup.BackupAgentHelper 
-keep public class * extends android.preference.Preference 
-keep public class com.android.vending.licensing.ILicensingService 
# (2)Simple XML 
-keep public class org.simpleframework.**{ *; } 
-keep class org.simpleframework.xml.**{ *; } 
-keep class org.simpleframework.xml.core.**{ *; } 
-keep class org.simpleframework.xml.util.**{ *; } 
# (1)Annotations and signatures 
-keepattributes *Annotation* 
-keepattributes Signature 

-keepclasseswithmembernames class * { 
    native <methods>; 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

-keepclassmembers class * extends android.app.Activity { 
    public void *(android.view.View); 
} 

-keepclassmembers enum * { 
    public static **[] values(); 
    public static ** valueOf(java.lang.String); 
} 

-keep class * implements android.os.Parcelable { 
    public static final android.os.Parcelable$Creator *; 
} 

lo uso en mi propio proyecto y funciona;)

1

Trate de añadir esto a su archivo de Proguard:

-keep public class org.simpleframework.** { *; } 
-keep class org.simpleframework.xml.** { *; } 
-keep class org.simpleframework.xml.core.** { *; } 
-keep class org.simpleframework.xml.util.** { *; } 

-keepattributes ElementList, Root 

-keepclassmembers class * { 
    @org.simpleframework.xml.* *; 
} 

que esto esté arreglado para mí.

2

seguí recibiendo los errores siguientes:

can't find referenced class javax.xml.stream.XMLEventReader

can't find referenced class javax.xml.stream.events.XMLEvent

Esto es porque estos son parte de la ejecución de Java (rt.jar), pero no forma parte del tiempo de ejecución de Android (android.jar), por lo ProGuard advierte que algo podría estar roto. Esto no es realmente un problema, por lo que se puede hacer lo siguiente:

-dontwarn javax.xml.stream.events.** 

Source

En combinación con la respuesta de zmicer, me sale el siguiente

-dontwarn javax.xml.stream.events.** 

-keep public class org.simpleframework.** { *; } 
-keep class org.simpleframework.xml.** { *; } 
-keep class org.simpleframework.xml.core.** { *; } 
-keep class org.simpleframework.xml.util.** { *; } 

-keepattributes ElementList, Root 

-keepclassmembers class * { 
    @org.simpleframework.xml.* *; 
} 
+0

99% esto, pero un poco diferente para 'dontwarn' y 'keepattributes'. -dontwarn javax.xml.stream. ** -keepattributes ElementList, Root, * Annotation * –

0

Esta adición a la exacta archivo de protección funcionó para mí:

-dontwarn javax.xml.stream.** 

-keep public class org.simpleframework.** { *; } 
-keep class org.simpleframework.xml.** { *; } 
-keep class org.simpleframework.xml.core.** { *; } 
-keep class org.simpleframework.xml.util.** { *; } 

-keepattributes ElementList, Root 

-keepclassmembers class * { 
    @org.simpleframework.xml.* *; 
} 
Cuestiones relacionadas