成功回调

时间:2015-12-16 09:46:26

标签: android gson proguard retrofit

我的第一个理解是,ProGuard导致无法在Retrofit成功回调中检索到响应对象。但问题是Retrofit会在成功回调中返回原始响应对象(第二个参数),具体取决于日志级别。

请参阅下面的答案。

Google报告的IOException:

  

com.google.a.ae:java.io.IOException:已关闭   com.google.a.k.a(未知来源)com.google.a.k.a(未知来源)     在com.myapp.rest.model.ApiResponse.parseResponse(未知来源)at at   com.myapp.service.e.a(未知来源)at   com.myapp.service.e.success(未知来源)at   retrofit.CallbackRunnable $ 1.run(未知来源)at   android.os.Handler.handleCallback(Handler.java:739)at   android.os.Handler.dispatchMessage(Handler.java:95)at   android.os.Looper.loop(Looper.java:155)at   android.app.ActivityThread.main(ActivityThread.java:5696)at   java.lang.reflect.Method.invoke(Native Method)at   java.lang.reflect.Method.invoke(Method.java:372)at   com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1028)     在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)   引起:java.io.IOException:在c.x.read处关闭(未知来源)     在java.io.InputStreamReader.read(InputStreamReader.java:231)at   java.io.BufferedReader.fillBuf(BufferedReader.java:145)at   java.io.BufferedReader.read(BufferedReader.java:333)at   com.google.a.d.a.b(未知来源)com.google.a.d.a.b(未知   来自)com.google.a.d.a.A(未知来源)at   来自com.google.a.d.a.f的com.google.a.d.a.o(未知来源)(未知   来源)......还有14个

异步改装请求:

@POST("/api/myobjects")
void newMyObject(@Body MyObject myObject, Callback<MyObject> cb);

Retrofit成功回调:

public void success(MyObject myObject, Response raw) {
    try { 
        ApiResponse res = ApiResponse.parseResponse(raw);
    } catch (IOException | NullPointerException e) {
        super.failure(RetrofitError.unexpectedError(raw.getUrl(), e));
    }
}

解析API响应:

public static ApiResponse parseResponse(Response response) throws IOException {
    final Gson gson = new Gson();
    final BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody().in()));
    return gson.fromJson(reader, ApiResponse.class);
}

按照Retrofit和Gson指南实施ProGuard:

-dontwarn rx.**
-dontwarn okio.**
-dontwarn jce.**
-dontwarn javax.naming.**

# keep okhttp & retrofit following retrofit guidelines
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }

-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
    @retrofit.http.* <methods>; }

# keep gson following google guidelines
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }

# keep application classes that are serialized/deserialized over Gson
-keep class com.myapp.rest.model.** { *; }

# keep the data for stacktraces
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes LineNumberTable
-keepattributes Exceptions

进一步分析显示响应可用, 但是在解析响应对象时,连接已经关闭。 下面的日志显示可以检索响应URL和状态 在Retrofit中成功回调。

  

12-17 10:39:46.639 4192-4192 /? I / com.myapp.service.e:   https://urlto/api/myobjects?locale=en&app=xxx 12-17 10:39:46.639   4192-4192 /? I / com.myapp.service.e:OK 12-17 10:39:46.649   4192-4192 /?W / dalvikvm:threadid = 1:线程退出未捕获   异常(组= 0x4208f8e0)12-17 10:39:46.669 4192-4192 /?   E / AndroidRuntime:FATAL EXCEPTION:主要是com.google.gson.ae:   java.io.IOException:在com.google.gson.k.a(未知来源)

处关闭

1 个答案:

答案 0 :(得分:1)

经过进一步的研究表明,当日志级别不是FULL时,Retrofit的一个已知功能是不返回原始响应体(Inputstream被读取和关闭)。

请参阅:https://github.com/square/retrofit/issues/953(已结束)。我不清楚为什么它会被关闭,因为第二个参数根据日志级别的行为会有不同的意外行为。

其他人建议的解决方法是在第一个参数中返回Response对象。另一种方法是将日志级别保持为FULL。