web-dev-qa-db-ja.com

proguardを有効にしてGSONを使用する

私のコードはプロガードなしでは完全に機能しますが、プロガードが有効になっているとGSONは機能しません。

これは動作しないコードの一部です

JSONArray mensaje = response.getJSONArray("categorias");
// Parsear con Gson
Categorias[] categorias = gson.fromJson(mensaje.toString(), Categorias[].class);
Log.d("mainfragment","desc categoria "+categorias[0].getDescripcionCategoria());

mainfragmentのログはnullを出力します

# Output
D/Dato categorias﹕ Respuesta: {"categorias":[{"idCategoria":"22","imagenCategoria":"ic_aseguradora","descripcionCategoria":"Aseguradoras"},{"idCategoria":"24","imagenCategoria":"ic_bar","descripcionCategoria":"Bares"},{"idCategoria":"12","imagenCategoria":"ic_boutique","descripcionCategoria":"Boutiques"},{"idCategoria":"6","imagenCategoria":"ic_cafe","descripcionCategoria":"Cafeterias"},{"idCategoria":"21","imagenCategoria":"ic_ciber","descripcionCategoria":"Ciber"},{"idCategoria":"10","imagenCategoria":"ic_estetica","descripcionCategoria":"Estéticas"},{"idCategoria":"1","imagenCategoria":"ic_farmacia","descripcionCategoria":"Farmacias"},{"idCategoria":"7","imagenCategoria":"ic_ferreteria","descripcionCategoria":"Ferreterias"},{"idCategoria":"16","imagenCategoria":"ic_gas","descripcionCategoria":"Gas"},{"idCategoria":"23","imagenCategoria":"ic_gasolinera","descripcionCategoria":"Gasolineras"},{"idCategoria":"4","imagenCategoria":"ic_gym","descripcionCategoria":"Gimnasios"},{"idCategoria":"2","imagenCategoria":"ic_hotel","descripcionCategoria":"Hoteles"},{"idCategoria":"15","imagenCategoria":"ic_lavanderia","descripcionCategoria":"Lavanderias"},{"idCategoria":"19","imagenCategoria":"ic_muebleria","descripcionCategoria":"Mueblerias"},{"idCategoria":"25","imagenCategoria":"ic_optica","descripcionCategoria":"Ópticas"},{"idCategoria":"20","imagenCategoria":"ic_pasteleria","descripcionCategoria":"Pastelerias"},{"idCategoria":"17","imagenCategoria":"ic_pizza","descripcionCategoria":"Pizzerías"},{"idCategoria":"13","imagenCategoria":"ic_purificadora","descripcionCategoria":"Purificadoras de agua"},{"idCategoria":"5","imagenCategoria":"ic_restaurant","descripcionCategoria":"Restaurantes"},{"idCategoria":"11","imagenCategoria":"ic_ropa","descripcionCategoria":"Ropa"},{"idCategoria":"9","imagenCategoria":"ic_salon","descripcionCategoria":"Salones de fiestas"},{"idCategoria":"3","imagenCategoria":"ic_sonido","descripcionCategoria":"Sonidos"},{"idCategoria":"28","imagenCategoria":"ic_taqueria","descripcionCategoria":"Taquería"},{"idCategoria":"8","imagenCategoria":"ic_taxi","descripcionCategoria":"Taxis"},{"idCategoria":"14","imagenCategoria":"ic_tortilleria","descripcionCategoria":"Tortillerias"},{"idCategoria":"27","imagenCategoria":"ic_veterinaria","descripcionCategoria":"Veterinarias"},{"idCategoria":"18","imagenCategoria":"ic_vinateria","descripcionCategoria":"Vinaterías"},{"idCategoria":"26","imagenCategoria":"ic_zapateria","descripcionCategoria":"Zapaterías"}],"estado":1}
D/mainfragment﹕ desc categoria null

これは私の保護ルールです

#GoogleMaps
-keep class * extends Java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.Android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.Android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @ccom.google.Android.gms.common.annotation.KeepName *;
}

-keepnames class * implements Android.os.Parcelable {
    public static final ** CREATOR;
}



#Volley?

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-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
-dontnote com.Android.vending.licensing.ILicensingService

-keepclassmembers class * implements Java.io.Serializable {
     static final long serialVersionUID;
     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();
 }


 -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 **.R$* {
   public static <fields>;
 }

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


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

-keep public class * {
     public protected *;
 }



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

 -keep class Android.support.v7.widget.SearchView
 -keep class Android.support.v7.widget.**{*;}
 -keep class Android.support.v4.app.** { *; }
 -keep interface Android.support.v4.app.** { *; }
 -keep class com.actionbarsherlock.** { *; }
 -keep interface com.actionbarsherlock.** { *; }
 -keep class com.Android.volley.** { *; }
 -keep interface com.Android.volley.** { *; }
 -keepattributes *Annotation*


##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
#-keepattributes *Annotation*
-keepattributes EnclosingMethod

# Gson specific classes
-keep class Sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
 -keep class Categorias.data.model.** { *; }
 -keep class Categorias.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.Android.model.** { *; }
-keep class com.puertosoft.appcomercialdelpuerto.Android.model.** { *; }
-keep class com.puertosoft.appcomercialdelpuerto.model.** { *; }
-keep class com.puertosoft.appcomercialdelpuerto.model.User { *; }

# Add the gson class
-keep public class com.google.gson

# Add any classes the interact with gson
-keep class com.puertosoft.appcomercialdelpuerto.models.ChatModel { *; }
-keep class com.puertosoft.appcomercialdelpuerto.models.FeedModel { *; }
-keep class com.puertosoft.appcomercialdelpuerto.Android.models.ChatModel { *; }
-keep class com.puertosoft.appcomercialdelpuerto.Android.models.FeedModel { *; }

-libraryjars /build/intermediates/pre-dexed/debug/gson-2.3-08958b96da94c86264ec30e35a9d524bac95d2df.jar




-printmapping outputfile.txt
-renamesourcefileattribute SourceFile
#-keepattributes SourceFile,LineNumberTable

これは影響を受けるクラスです

public class Categorias {

    private String idCategoria;
    private String descripcionCategoria;
    private String imagenCategoria;

    public Categorias(String idCategoria, String descripcionCategoria, String imagenCategoria){
        this.idCategoria=idCategoria;
        this.descripcionCategoria=descripcionCategoria;
        this.imagenCategoria=imagenCategoria;
    }

    public String getIdCategoria(){
        return idCategoria;
    }

    public String getDescripcionCategoria(){
        return descripcionCategoria;
    }

    public String getImagenCategoria(){
        return imagenCategoria;
    }

}

変数名はプロガードで難読化され、次のようなものが残ります。

private String a;

の代わりに

private String descripcionCategoria;

一部のクラスが難読化されないように、プロガードルールを追加できます。私はこれらを使って逃げました:

-keepattributes Signature
# POJOs used with GSON
# The variable names are JSON key values and should not be obfuscated
-keepclassmembers class com.example.apps.Android.Categorias { <fields>; }
# You can apply the rule to all the affected classes also
# -keepclassmembers class com.example.apps.Android.model.** { <fields>; }

POJOクラス名が解析にも使用される場合は、ルールも追加する必要があります

-keep class com.example.apps.Android.model.** { <fields>; }

あなたの場合、注釈は使用されていません。

# Keep the annotations
-keepattributes *Annotation*

別の方法この問題を解決するには、SerializedName注釈を使用して、クラスを難読化することです。このためには、-keepattributes *Annotation*ルールがまだ必要です。

import com.google.gson.annotations.SerializedName

@SerializedName("descripcionCategoria")
private String descripcionCategoria;
59
Sebastian

モデルをまだ難読化したい場合は、注釈@SerializedName("name_of_json_field")を使用します。 gsonにフィールドの実際の名前を知らせます。

あなたも必要だと思う

-keepattributes *Annotation*

注釈が難読化されないようにする

22
ar-g

モデルクラスの難読化を除外する必要があります以下のように、パッケージin.intellicode.webservicesのすべてのモデルクラスを除外しました。モデル

-keep class in.intellicode.webservices.models.** { *; }
-keep class in.intellicode.models.** { *; }
-keep class in.intellicode.events.*{ *; }

-keepattributes Signature
-keepattributes *Annotation*
-keep class Sun.misc.Unsafe { *; }
14
Kirtan

モデルクラスにproguardスクリプトを適用すると、名前とプロパティの名前が難読化されます。したがって、String descripcionCategoria;を難読化すると、String aaaa;のようなものになります

GsonはJavaリフレクションを介して機能し、データの解析中にプロパティ名を使用しようとします。そのため、難読化をモデルクラスに適用すると、データを解析できなくなります。

そのため、proguardスクリプトからモデルクラスを除外すると、再度解析できるようになります。

3