Search code examples
androidretrofit2proguardobfuscation

API is not working when ProGuard is activated in my Android app


After enabling minifyEnabled=true API is not sending data to server. When I checked in the server, I am getting all the inputs are null. However, if I add -dontobfuscate in "proguard-rules.pro" file then the app is working fine. I am using retrofit2. I tried almost all the ProGuard rules regarding the retrofit2. Nothing worked!.

My build.gradle file:

def lifecycleExtensionVersion = '2.2.0'
def butterknifeVersion = '10.1.0'
def supportVersion = '29.0.0'
def retrofitVersion = '2.3.0'
def glideVersion = '4.9.0'
def rxJavaVersion = '2.1.1'
def daggerVersion = '2.14.1'
def mockitoVersion = '2.11.0'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
    implementation 'com.google.firebase:firebase-messaging:20.2.4'
    implementation 'com.google.firebase:firebase-analytics:17.5.0'
    implementation 'com.google.firebase:firebase-auth:19.3.0'

    implementation "com.android.support:design:$supportVersion"
    implementation "android.arch.lifecycle:extensions:$lifecycleExtensionVersion"

    implementation "com.jakewharton:butterknife:$butterknifeVersion"
    implementation 'androidx.work:work-runtime:2.2.0'
    annotationProcessor "com.jakewharton:butterknife-compiler:$butterknifeVersion"

    implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
    implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
    implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion"

    implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
    implementation "io.reactivex.rxjava2:rxandroid:$rxJavaVersion"

    implementation "com.github.bumptech.glide:glide:$glideVersion"

    implementation "com.google.dagger:dagger:$daggerVersion"
    implementation "com.google.dagger:dagger-android-support:$daggerVersion"
    implementation "androidx.legacy:legacy-support-v4:1.0.0"
    annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
    annotationProcessor "com.google.dagger:dagger-android-processor:$daggerVersion"

    implementation 'com.airbnb:deeplinkdispatch:4.1.0'
    annotationProcessor 'com.airbnb:deeplinkdispatch-processor:4.1.0'

    testImplementation "org.mockito:mockito-inline:$mockitoVersion"
    testImplementation "android.arch.core:core-testing:1.1.1"

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

}

Also, when minifyEnabled=true, the following "getLoginResult" function is not reaching when I debug. But when I add -dontobfuscate then it reaches.

LoginViewModel.Java

import android.util.Log;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import io.reactivex.disposables.CompositeDisposable;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


public class LoginViewModel extends ViewModel {

    public MutableLiveData<LoginUser> loginUser = new MutableLiveData<>();
    public MutableLiveData<Boolean> loginUserLoadError = new MutableLiveData<>();
    public MutableLiveData<Boolean> loading = new MutableLiveData<>();

    private CompositeDisposable disposable = new CompositeDisposable();

    public LiveData<ResponseBody> getLoginResult(String getEmail, String getPassword, String device_ip){
        loading.setValue(true);

        final MutableLiveData<ResponseBody> outputReponse = new MutableLiveData<>();

        LoginUser loginUser = new LoginUser(getEmail, getPassword, device_ip);

        Call<ResponseBody> call = LoginService
                .getInstance()
                .getLoginAPI()
                .loginUser(loginUser);

        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                outputReponse.setValue(response.body());
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.d("Login Failed", t.getLocalizedMessage());
            }
        });

        return outputReponse;
    }

What I am missing or doing wrong here? How can I get it work.


Solution

  • Two way you can fix this:

    1. Insert Annotation Keep for all response and request DTO Class.

    2. Fix to keep all class do you need in proguard-rules.pro file like this :

    -ignorewarnings
    -keep class * {
        public private *;
    }
    
    -keep class com.google.android.gms.** { *; }
    -dontwarn com.google.android.gms.**
    
    -dontwarn org.xmlpull.v1.**
    -dontnote org.xmlpull.v1.**
    -keep class org.xmlpull.** { *; }
    
    #retRofit
    # Platform calls Class.forName on types which do not exist on Android to determine platform.
    -dontnote retrofit2.Platform
    # Platform used when running on RoboVM on iOS. Will not be used at runtime.
    -dontnote retrofit2.Platform$IOS$MainThreadExecutor
    # Platform used when running on Java 8 VMs. Will not be used at runtime.
    -dontwarn retrofit2.Platform$Java8
    # Retain generic type information for use by reflection by converters and adapters.
    -keepattributes Signature
    # Retain declared checked exceptions for use by a Proxy instance.
    -keepattributes Exceptions
    -keepclasseswithmembers class * {
        @retrofit2.http.* <methods>;
    }
    # Orm
    -keep class * extends com.raizlabs.android.dbflow.config.DatabaseHolder { *; }
    
    # Fresco
    
    -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
    -keep @com.facebook.common.internal.DoNotStrip class *
    -keepclassmembers class * {
        @com.facebook.common.internal.DoNotStrip *;
    }
    -keepclassmembers class * {
        native <methods>;
    }
    -dontwarn okio.**
    -dontwarn com.squareup.okhttp.**
    -dontwarn okhttp3.**
    -dontwarn javax.annotation.**
    -dontwarn com.android.volley.toolbox.**
    
    # com.github.siyamed:android-shape-imageview
    -dontwarn android.support.v7.**
    -keepattributes *Annotation,Signature
    -dontwarn com.github.siyamed.**
    -keep class com.github.siyamed.shapeimageview.**{ *; }
    -dontwarn org.xmlpull.v1.**
    -dontwarn uk.co.senab.photoview.**
    
    #Image Cropper
    -keep class androidx.appcompat.widget.** { *; }
    
    
    
    # Keep source file names, line numbers, and Parse class/method names for easier debugging
     -keepattributes SourceFile,LineNumberTable
     -keepnames class com.parse.** { *; }
    
    
     # Required for Parse
     -keepattributes *Annotation*
     -keepattributes Signature
     -dontwarn com.squareup.**
     -dontwarn okio.**
    
    
    -keepattributes SourceFile,LineNumberTable
    -keep class com.parse.*{ *; }
    -dontwarn com.parse.**
    -dontwarn com.squareup.picasso.**
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    ```