Retrofit 2 not sending data when ProGuard is enabled
Solution 1
I finally managed to make it work. Here is the proguard configuration regarding Retrofit 2
# Retrofit
-dontwarn retrofit2.**
-dontwarn org.codehaus.mojo.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
-keepattributes EnclosingMethod
-keepclasseswithmembers class * {
@retrofit2.* <methods>;
}
-keepclasseswithmembers interface * {
@retrofit2.* <methods>;
}
Thanks @xudshen
UPDATE
The main problem: I used proguard-android-optimize So I should added:
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
I also switched back to the regular Retrofit 2 proguard config provided by square :
# 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
Solution 2
Adding to @Romain's answer You Need to add to proguard file
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
If you are using @Header, @Query...
Reference from here Retrofit2 proguard remove param
Solution 3
finally i find.
just try this if you use Gson
,
add this to retrofit pro-guard :
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
then use @SerializedName("name")
in your model .kotlin
example:
class PaymentRequestModel (
@SerializedName("name")
@Expose
var name : String = "",
}
Solution 4
Another simple solution use @keep from support annotation https://developer.android.com/reference/android/support/annotation/Keep.html
@Keep
interface APIService
{
@GET("/user/auth")
fun auth(@Header(Constants.AUTHORIZATION) authorization: String): Call<User>
}
Solution 5
for me works using annotation @SerializedName
public class YourJsonClass{
@SerializedName("name") String username;
...
}
Related videos on Youtube
Comments
-
Romain almost 2 years
I try to login my users using Retrofit 2. (Basically a GET to the login URL with a basic header) It works well but once I ProGuard it, the Header Authorization is not sent anymore. (See log outputs)
Sample code :
User Model :
public interface UserService { @GET(GET_LOGIN) Observable<User> login(@Header("Authorization") String basic); }
Login Activity :
public void onClick(View v) { mRetrofit.create(UserService.class) .login(Credentials.basic(email, password)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> { UserHelper.save(LoginActivity.this, user); }, throwable -> Dog.d); }
Proguard File :
# Retrofit -dontwarn retrofit2.** -dontwarn org.codehaus.mojo.** -keep class retrofit2.** { *; } -keepattributes Signature -keepattributes Exceptions -keepattributes *Annotation* -keepclasseswithmembers class * { @retrofit.* <methods>; } -keepclasseswithmembers interface * { @retrofit.* <methods>; }
Logs (proguard) :
D/OkHttp: --> GET http://passport-supercairos.rhcloud.com/users/login HTTP/1.1 D/OkHttp: User-Agent: VirtualPassport-Client {Android-23} {Aquaris_E5} D/OkHttp: Cache-Control: max-stale=10800 D/OkHttp: --> END GET D/OkHttp: <-- HTTP/1.1 401 Unauthorized (258ms) D/OkHttp: Date: Fri, 19 Feb 2016 12:57:19 GMT D/OkHttp: X-Powered-By: Express D/OkHttp: WWW-Authenticate: Basic realm="Users" D/OkHttp: Keep-Alive: timeout=15, max=100 D/OkHttp: Connection: Keep-Alive D/OkHttp: Transfer-Encoding: chunked D/OkHttp: Content-Type: text/plain D/OkHttp: OkHttp-Sent-Millis: 1455886639681 D/OkHttp: OkHttp-Received-Millis: 1455886639787 D/OkHttp: Unauthorized D/OkHttp: <-- END HTTP (12-byte body)
Logs (non-proguard) :
D/OkHttp: --> GET http://passport-supercairos.rhcloud.com/users/login HTTP/1.1 D/OkHttp: User-Agent: VirtualPassport-Client {Android-23} {Aquaris_E5} D/OkHttp: Cache-Control: max-stale=10800 D/OkHttp: Authorization: Basic ZG9yb2ZyanVAZ21haWwuY29tOmN2dnZ2dnY= D/OkHttp: --> END GET D/OkHttp: <-- HTTP/1.1 401 Unauthorized (258ms) D/OkHttp: Date: Fri, 19 Feb 2016 12:57:19 GMT D/OkHttp: X-Powered-By: Express D/OkHttp: WWW-Authenticate: Basic realm="Users" D/OkHttp: Keep-Alive: timeout=15, max=100 D/OkHttp: Connection: Keep-Alive D/OkHttp: Transfer-Encoding: chunked D/OkHttp: Content-Type: text/plain D/OkHttp: OkHttp-Sent-Millis: 1455886639681 D/OkHttp: OkHttp-Received-Millis: 1455886639787 D/OkHttp: Unauthorized D/OkHttp: <-- END HTTP (12-byte body)
Full code can be found here : https://github.com/supercairos/virtual-passport
-
Romain about 8 yearsI think the main problem is that proguard strip the @Header("Authorization") annotation. But i have no idea why. Especially since I explicitly told him to keep -keepattributes Annotation
-
-
Benni over 7 yearsDidn't work for me...still got the same error after trying this and all the other rules i could possibly find. Linked the rules since it's too long for the comment. link
-
Shivang over 7 yearsNot working, I am still not able to send request parameters
-
Mansuu.... almost 7 yearsYeah me too getting same problem
-
Kalaiselvan over 3 yearsI was facing issue in retrofit json parsing. This happened when I change minifyEnabled to true in release build. adding the above in line proguard fixed my issue. Also If you use data class for request body in retrofit post requests, then adding @SerializedName("") is also important.
-
Arbaz.in over 3 yearsi used headers,query,post and body for request and that is not working when proguard is enable can you please tell me what i have to change?
-
mhKarami over 3 years@Arbaz.in you should add pro-guards of all libraries you are using to your app pro-guard for example retrofit , Gson ,.. .
-
Abdul Salam almost 2 yearsdid not worked for me, i am using:
Call<AssignmentResponse> fetchAssignment(@Query("user") String user);