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*
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é.
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.
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 ----------
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.
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
)
Vous devrez peut-être utiliser
-keepclassmembers enum * { *; }
garder vos énumérations
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