web-dev-qa-db-fra.com

Exception fatale: Java.lang.NullPointerException dans la version

Je suis confronté à un problème étrange dans la version finale de l'application. Voici mon exception

Fatal Exception: Java.lang.NullPointerException`
throw with null exception
in.hopq.hopq.authentication.models.AppUpdateSourceDO$AppUpdate.getMinAllowedVersion (AppUpdateSourceDO.Java:3)
in.hopq.hopq.authentication.activities.SplashActivity$onCreate$1.onChanged (SplashActivity.Java:48)
in.hopq.hopq.authentication.activities.SplashActivity$onCreate$1.onChanged (SplashActivity.Java:31)

Fichier Pojo

data class AppUpdateSourceDO(
    @SerializedName("app_update")
    val appUpdate: AppUpdate,
    @SerializedName("message")
    val message: String,
    @SerializedName("success")
    val success: Boolean
) {
data class AppUpdate(
        @SerializedName("excluded_versions")
        val excludedVersions: List<ExcludedVersion>,
        @SerializedName("min_allowed_version")
        val minAllowedVersion: Int,
        @SerializedName("min_allowed_version_ios")
        val minAllowedVersionIos: String,
        @SerializedName("recommended_version")
        val recommendedVersion: Int?
) {
    data class ExcludedVersion(
            @SerializedName("version")
            val version: String
    )
}
}

Voici mon fichier proguard

##OKHTTP3
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-dontnote okhttp3.**
-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
# 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*
14
pratham kesarkar

Enfin résolu ce problème. Cela est dû à l'obscurcissement du nouveau code R8. Désactivez-le simplement de votre projet en l'ajoutant au fichier gradle.properties

Android.enableR8=false

De plus, vous l'ajoutez à votre fichier de règles proguard.

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

Cependant, cela n'a pas vraiment fonctionné.

22
pratham kesarkar

Désactiver R8 peut ne pas être une bonne idée. Mais en ajoutant des lignes ci-dessous dans votre fichier Proguard Rules pourrait résoudre le problème -

-keepclassmembers,allowobfuscation class * {
    @com.google.gson.annotations.SerializedName <fields>;
  }
-keep,allowobfuscation @interface com.google.gson.annotations.SerializedName

Ceci est également suggéré par l'un des développeurs de Google comme la solution souhaitée. Vous pouvez trouver sa réponse ici et vous pouvez également suivre toute la discussion autour d'elle.

8
Abhishek

Il semble que GSON et R8 ne fonctionnent pas bien ensemble, et il est écrit à propos de ici :

En fait, les éléments suivants devraient également fonctionner:

-keepclassmembers, classe allowobfuscation * {@ com.google.gson.annotations.SerializedName; } -keep, allowobfuscation @interface com.google.gson.annotations.SerializedName

Cela réduira (masquera) également les noms des champs et de l'attribut, afin de réduire davantage la taille de l'APK final.

De plus, vous pouvez voir les règles suivantes dans l'exemple de Gson :

##---------------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*

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

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

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

##---------------End: proguard configuration for Gson  ----------
6
android developer

En utilisant @Keep l'annotation peut être une alternative raisonnable pour traiter les fichiers proguard. Annotez simplement votre classe de données avec @Keep et toute la classe avec ses membres ne sera pas réduite.

Il est particulièrement utile lorsque les noms de toutes les propriétés correspondent aux noms des champs json et qu'il n'est pas nécessaire d'annoter les propriétés avec @SerializedName. Règles de progression pour les classes avec @SerializedName les champs annotés (mentionnés dans d'autres réponses) ne s'appliquent pas à un tel cas.

1
art

Je suppose que vous recevez null dans le champ json min_allowed_version en raison de l'exception est clairement tapé:

Fatal Exception: Java.lang.NullPointerException throw with null 
exceptionin.hopq.hopq.authentication.models.AppUpdateSourceDO$AppUpdate.getMinAllowedVersion (AppUpdateSourceDO.Java:3)

Cela signifie que lorsque vous appelez getter du champ minAllowedVersion et que son retour est nul, vous avez attrapé NPE. Essayez d'utiliser la sécurité nulle et peut-être que tout fonctionnera bien.

data class AppUpdate(
        @SerializedName("excluded_versions")
        val excludedVersions: List<ExcludedVersion> = listOf(),
        @SerializedName("min_allowed_version")
        val minAllowedVersion: Int? = null,
        @SerializedName("min_allowed_version_ios")
        val minAllowedVersionIos: String? = null,
        @SerializedName("recommended_version")
        val recommendedVersion: Int? = null
)
1
Scrobot

Vous devrez peut-être utiliser

-keepclassmembers enum * { *; }

garder vos énumérations

0
Barral

Si l'annotation @SerializedName est utilisée de manière cohérente pour les classes de données, la règle de conservation suivante peut être utilisée

-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
 }

Si l'annotation @SerializedName n'est pas utilisée, la règle conservatrice suivante peut être utilisée pour chaque classe de données:

-keepclassmembers class MyDataClass {
  !transient <fields>;
 }

Pour plus d'informations, vous pouvez consulter le lien ci-dessous: -

https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md

0
Bhaven Shah