11

I'm retrieving a json and when I convert it to List using gson, the app crashes. The proguard is on and the problem is there.

fun getQuestions(): List<Question>? {
    val json = getQuestionsJsonData()
    return GsonBuilder().create().fromJson(
        json,
        object : TypeToken<List<Question>?>() {}.type
    )
}

As I've obfuscated my code, I'm not able to see crash log in logcat, so I send it to firebase crashlitycs. The error message is - Caused by java.lang.RuntimeException: Missing type parameter.

Maybe the Question type get's obfuscated or something similar happens. My proguard file:

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

-keepclassmembers class **.R$* {
    public static <fields>;
}

#Serialized
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    !private <fields>;
    !private <methods>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

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

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

Maybe I have to add something in proguard file?

P.S. The problem is only on Gradle 7.1.0

Hayk Mkrtchyan
  • 2,835
  • 3
  • 19
  • 61

5 Answers5

32

In my case was just adding the following to proguard configuration:

# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

Here you go the full set of options that are needed for Gson -> https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg

forlayo
  • 1,371
  • 2
  • 13
  • 23
15

Well, after changing my TypeToken code, seems it's working.

Non working code:

return GsonBuilder().create().fromJson(
    json,
    object : TypeToken<List<Question>?>() {}.type
)

Working solution:

return GsonBuilder().create().fromJson(
    json,
    TypeToken.getParameterized(List::class.java, Question::class.java).type
)
Hayk Mkrtchyan
  • 2,835
  • 3
  • 19
  • 61
3

Add these 3 lines inside proguard-rules.pro :

-keep class com.google.gson.reflect.TypeToken
-keep class * extends com.google.gson.reflect.TypeToken
-keep public class * implements java.lang.reflect.Type
Ashraf Amin
  • 343
  • 3
  • 7
1

There have been some breaking changes in the Android Gradle plugin v8.0, including the enabling of R8 full mode: https://developer.android.com/build/releases/gradle-plugin#default-changes

If none of the other options, such as keeping TypeToken classes, works for you, you can add the following command to your gradle.properties:

android.enableR8.fullMode = false

You can read more about R8 full mode here: https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md#r8-full-mode

AliSh
  • 10,085
  • 5
  • 44
  • 76
0

Add these lines inside proguard-rules.pro

# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
-keep class com.google.gson.reflect.TypeToken
-keep class * extends com.google.gson.reflect.TypeToken
-keep public class * implements java.lang.reflect.Type
Attaullah
  • 3,856
  • 3
  • 48
  • 63