web-dev-qa-db-ja.com

RetroGuard 2がProGuardが有効な場合にデータを送信しない

Retrofit 2を使用してユーザーをログインしようとします(基本的には、基本ヘッダーを含むログインURLへのGET)。 (ログ出力を参照)

サンプルコード:

ユーザーモデル:

public interface UserService {

    @GET(GET_LOGIN)
    Observable<User> login(@Header("Authorization") String basic);
}

ログインアクティビティ:

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ファイル:

# Retrofit
-dontwarn retrofit2.** 
-dontwarn org.codehaus.mojo.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepclasseswithmembers class * {
    @retrofit.* <methods>;
}

-keepclasseswithmembers interface * {
    @retrofit.* <methods>;
}

ログ(プロガード):

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)

ログ(プロガード以外):

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)

完全なコードはここにあります: https://github.com/supercairos/virtual-passport

22
Romain

ようやくそれを機能させることができました。改造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>;
}

ありがとう@ xudshen

[〜#〜]更新[〜#〜]

主な問題:proguard-Android-optimizeを使用したので、追加する必要があります。

-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}

また、squareが提供する通常のRetrofit 2 proguard構成に戻しました。

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

@Romainの回答に追加するProguardファイルに追加する必要があります

-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}

@ Header、@ Queryを使用している場合...

ここからの参照 Retrofit2 proguard remove param

11
silentsudo

別の簡単なソリューションでは、@ keep from supportアノテーションを使用します 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>

}
7
Pauland

私にとってはアノテーション@SerializedNameを使用して動作します

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

   ...
 }
4
Peter

やっと見つけた。 Gsonを使用する場合は、これを試してください。これをプロガードを改造するために追加してください:

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

次に、モデルで@SerializedName("name")を使用します。kotlinの例:

_class PaymentRequestModel (
    @SerializedName("name")
    @Expose
    var name : String = "",
}
_
1
mhKarami

Retrofit 2とProguardコードObfuscatorの互換性を追加

    -dontwarn retrofit.**
    -keep class retrofit.** { *; }
    -keepattributes Signature
    -keepattributes Exceptions
    -dontwarn Java.lang.invoke.*
    -keep class com.elephantmobile.ui.remote.model.** { *; }
    -dontwarn retrofit.appengine.UrlFetchClient
    -keepclasseswithmembers class * {
        @retrofit.http.* <methods>;
    }
    -keepclassmembernames interface * {
        @retrofit.http.* <methods>;
    }
    -dontwarn retrofit2.Platform$Java8
0
Duna