Retrofit2 not working when enabling Proguard

2.9k Views Asked by At

I have an application which uses retrofit to fetch logo form an API.

When i don't obfuscate and shrink my code, everything works fine. But when i enable it, the API call stops working. I don't get any crash or error messages, i just don't get any values from the API.

gradle

buildTypes {
    debug{
        // Enables code shrinking, obfuscation, and optimization for only
        // your project's release build type.
        minifyEnabled true

        // Enables resource shrinking, which is performed by the
        // Android Gradle plugin.
        shrinkResources true

        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.debug
    }
    release {
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

I used it in debug just for testing purposes. If i use it in release, it has same output.

I checked the retrofit page and they advised to use the following file

proguard-rules.pro

# 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
-printusage usage.txt

-keep class com.th3pl4gu3.locky_offline.core.main.** {*;}
-keep class com.th3pl4gu3.locky_offline.repository.network.** {*;}
-keep class com.th3pl4gu3.locky_offline.repository.database.** {*;}

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

The API call still doesn't work. I tried many posts on stackoverflow but nothing works for me. Can someone help me by proposing a solution or an alternative to this ?

Thank you

2

There are 2 best solutions below

0
On
  1. Use progaurd rules from the official retrofit site https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro

  2. Sometimes issue seems to be from retrofit but it is not. It’s a GSON and ProGuard problem. To fix it you just have to add a -keep class configuration in your proguard rules of the package where your Pojo class is stored For example my API response and request classes are stored like this (package name may differ according to your app):

-keep class com.sample.myapp.model.request. { ; }
-keep class com.sample.myapp.model.model.response.
* { ; }*

1
On

Have you tried to put @SerializedName to Object field?

public class YourJsonClass{
    @SerializedName("username") 
    String username;
}