Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I can not debug Proxy.newProxyInstance method?

I am using Retrofit on Android.

I define a service GitHubService.

public interface GithubService {

    @GET("users/{user}")
    Call<ResponseBody> fetchUserInfo(@Path("user") String user);

}

Then I create service.

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://api.github.com")
        .build();

GithubService service = retrofit.create(GithubService.class);
Call<ResponseBody> call = service.fetchUserInfo("coxier");
call.enqueue(...);

As you see, I use above code to get user info of github. And above code works well for me. Now I want to know how Retofit works so I read source code.The code below is Retrofit#create. After reading, I still don't know its magic then I decide to debug Retroft.

public <T> T create(final Class<T> service) {
  ...
  return (T) Proxy.newProxyInstance(...,
      new InvocationHandler() {
        ...
        @Override public Object invoke(..)
            throws Throwable {

          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          ...
          return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
        }
      });
}

I debug at if(method.getDeclaringClass() == Object.class) line ,however it crashes. I don't know why it crashes.

EDIT

I tested several devices.

  • Nexus 6P Android 8.0 : crash when debug
  • Xiaomi 6 Android 8.1: crash when debug
  • OnePlus 3 Android 8.0: crash when debug
  • Nexus 6P Android 7.0:works well when debug
  • Oppo Android 6.0: works well when debug
  • Samsung S4 Android 5.0: works well when debug

It may crash above Android 8.0.

like image 298
CoXier Avatar asked Sep 26 '18 02:09

CoXier


2 Answers

Since the crashes occur with Android 8 and higher, I suppose it has to do with the restrictions of that versions in regard of apps running in background.

I suppose, that due to your debugging efforts, the app stays active in background for too long, causing the system to eventually kill it.

However, there should be something in the Logcat about that. Perhaps you see it, if you remove any filters from the Logcat window.

like image 194
Ridcully Avatar answered Nov 16 '22 20:11

Ridcully


Now I want to know how Retofit works so I read source code.

Is this what You were trying to achieve? By adding interceptor You will be able see the requests in logcat.

private RestApiStack() {

    OkHttpClient.Builder builder = new OkHttpClient.Builder();

    // preview requests
    if (BuildConfig.DEBUG) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(interceptor);
    }

    OkHttpClient client = builder.build();

    Retrofit retrofit = (new Retrofit.Builder())
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(/*...*/)
            .build();

    api = retrofit.create(ApiStack.class);
}

Dependencies:

implementation "com.squareup.okhttp3:logging-interceptor:3.9.1"
implementation "com.squareup.okhttp3:okhttp:3.11.0"
like image 26
deadfish Avatar answered Nov 16 '22 20:11

deadfish