web-dev-qa-db-fra.com

Moshi KotlinJsonAdapterFactory ne peut pas analyser Json après avoir activé minify

J'ai développé une application Android, utilisant Moshi comme l'une de ses dépendances.

Aujourd'hui, je veux activer minify pour ce projet. J'ai donc mis minifyEnabled true Dans mon build.gradle.

Après cela, j'ai constaté que toutes les réponses du serveur deviennent nulles.

Tout d'abord, j'utilise Retrofit2 pour appeler des API. Le corps JSON dans Response.body() n'est pas nul et a des valeurs correctes.

Le corps de réponse est le suivant (simplifié):

{"status":"success","data":{"user": "I am a user"}}

Et j'utilise le code ci-dessous pour le convertir en mon propre objet:

val someResponse = Moshi.Builder().add(KotlinJsonAdapterFactory()).build().adapter(SomeResponse::class.Java).fromJson(theJsonString)

Alors que le code pour SomeResponse:

class SomeResponse {
    @Json(name="status")
    var status: String? = null

    @Json(name="data")
    var data: User? = null
}

Et puis j'utilise simplement Log.i("Moshi", "${someResponse.status}" Pour voir la valeur, et le résultat est null.

J'ai déjà inclus les règles de proguard spécifiées dans la section README de Moshi Github, qui est celle-ci et celle-ci .

Pourquoi et comment résoudre ce problème?

Pour référence, voici mon proguard-rules.pro Complet:

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.Android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}

# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes SourceFile,LineNumberTable, *Annotation*

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


#Crashlytics: https://docs.fabric.io/Android/crashlytics/dex-and-proguard.html
-keepattributes *Annotation*
-keep public class * extends Java.lang.Exception


#https://stackoverflow.com/questions/36816521/is-the-format-of-the-data-held-in-kotlin-metadata-documented-anywhere
-dontwarn kotlin.**
-dontwarn kotlin.reflect.jvm.internal.**
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class kotlin.Metadata { *; }
-keepclassmembers public class com.example.app.** {
    public synthetic <methods>;
}
-keepclassmembers class kotlin.Metadata {
    public <methods>;
}
-keepclassmembers class **$WhenMappings {
    <fields>;
}
-keep class kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoaderImpl

#All models
-keep class com.example.app.models.**

#######Retrofit#######
#https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions

# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>



#######OkHttp3######
#https://github.com/square/okhttp/blob/master/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**

# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase

# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*

# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform




######Okio######
#https://github.com/square/okio/blob/master/okio/src/jvmMain/resources/META-INF/proguard/okio.pro
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*





####Moshi####
#https://github.com/square/moshi/blob/master/moshi/src/main/resources/META-INF/proguard/moshi.pro
#https://github.com/square/moshi/blob/master/kotlin/reflect/src/main/resources/META-INF/proguard/moshi-kotlin.pro
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**

-keepclasseswithmembers class * {
    @com.squareup.moshi.* <methods>;
}

-keep @com.squareup.moshi.JsonQualifier interface *

# Enum field names are used by the integrated EnumJsonAdapter.
# Annotate enums with @JsonClass(generateAdapter = false) to use them with Moshi.
-keepclassmembers @com.squareup.moshi.JsonClass class * extends Java.lang.Enum {
    <fields>;
}

# The name of @JsonClass types is used to look up the generated adapter.
-keepnames @com.squareup.moshi.JsonClass class *

# Retain generated JsonAdapters if annotated type is retained.
-if @com.squareup.moshi.JsonClass class *
-keep class <1>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*
-keep class <1>_<2>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*
-keep class <1>_<2>_<3>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*$*
-keep class <1>_<2>_<3>_<4>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*$*$*
-keep class <1>_<2>_<3>_<4>_<5>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*$*$*$*
-keep class <1>_<2>_<3>_<4>_<5>_<6>JsonAdapter {
    <init>(...);
    <fields>;
}
-keep class kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoaderImpl

-keepclassmembers class kotlin.Metadata {
    public <methods>;
}






####Mp4 Marser####
-keep class com.coremedia.iso.** {*;}
-keep class com.googlecode.mp4parser.** {*;}
-keep class com.mp4parser.** {*;}

-dontwarn com.coremedia.**
-dontwarn com.googlecode.mp4parser.**



####Picasso#####
#https://github.com/square/picasso/blob/master/picasso/consumer-proguard-rules.txt
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote okhttp3.internal.Platform
# Java.nio.file.* usage which cannot be used at runtime. Animal sniffer annotation.
-dontwarn okio.Okio
# JDK 7-only method which is @hide on Android. Animal sniffer annotation.
-dontwarn okio.DeflaterSink



#Ignore all other 3rd party libraries for now as we don't really care about the size but more about code obfuscation.
-keep class de.hdodenhof.**
-keep class io.github.luizgrp.sectionedrecyclerviewadapter.**
-keep class q.rorbin.badgeview.**
-keep class com.theartofdev.edmodo.**
-keep class me.relex
-keep class com.tbruyelle.rxpermissions2.**
-keep class com.github.pwittchen.reactivenetwork.**
-keep class com.minimize.Android.rxrecycleradapter.**
-keep class at.blogc.Android.**
-keep class com.yarolegovich.**
-keep class cn.trinea.Android.view.autoscrollviewpager.**
-keep class com.apkfuns.logutils.**
11
Sira Lam
-keepclasseswithmembers class * {
    @com.squareup.moshi.* <methods>;
}
-keep @com.squareup.moshi.JsonQualifier interface *
-dontwarn org.jetbrains.annotations.**
-keep class kotlin.Metadata { *; }
-keepclassmembers class kotlin.Metadata {
    public <methods>;
}

-keepclassmembers class * {
    @com.squareup.moshi.FromJson <methods>;
    @com.squareup.moshi.ToJson <methods>;
}

-keepnames @kotlin.Metadata class (Change with Yourpackagename) com.myapp.packagename.model.**
-keep class (Change with Yourpackagename) com.myapp.packagnename.model.** { *; }
-keepclassmembers class (Change with Yourpackagename) com.myapp.packagename.model.** { *; }

Remplacez com.myapp.packagnename par votre nom de pack

[~ # ~] ou [~ # ~]

Remplacez moshi-kotlin par kotshi qui joue bien avec Proguard sans règles spéciales, laissant tomber des centaines de kilo-octets dans l'apk final.

1
Sachin Kasaraddi

Essayez d'ajouter ceci à votre fichier proguard-rules.pro. J'espère que cela vous aidera.

# Moshi
-keepclassmembers class ** {
  @com.squareup.moshi.FromJson *;
  @com.squareup.moshi.ToJson *;
}
0
ArbenMaloku

Je pense que la solution ici est simple: Ajoutez une @Keep - Annotation à votre modèle (une certaine réponse), les noms de marshalling ne devraient plus être obscurcis. :-)

0
Zholoth

Vous pouvez également utiliser le processeur d'annotation Moshi "codegen".

Ajoutez la dépendance:

kapt "com.squareup.moshi:moshi-kotlin-codegen:1.9.2"

Annotez ensuite vos modèles avec @JsonClass:

@JsonClass(generateAdapter = true)
data class MyModel(...)

Vous devez également annoter toutes les classes d'énumération utilisées par les modèles, mais elles n'ont pas besoin d'un adaptateur:

@JsonClass(generateAdapter = false)
enum class MyEnumClass { ... }

Les règles de Moshi Proguard mentionnées précédemment de ici et ici sont également requises.

0
Philio