How can I debug my retrofit API call?
Solution 1
Use HttpLoggingInterceptor along with Retrofit.
If this helps, add this inside your build.gradle -
//Retrofit and OkHttp for Networking
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//Logging Network Calls
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
Inside your APIClient class
add this -
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
if(retrofit==null){
retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
}
return retrofit;
}
}
Kotlin Code
val interceptor : HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
val client : OkHttpClient = OkHttpClient.Builder().apply {
addInterceptor(interceptor)
}.build()
fun getService(): Service {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.client(client)
.build()
.create(Service::class.java)
}
And you will be able to log the Retrofit Network calls that you make.
Let me know if you need more information.
Solution 2
An OkHttp interceptor which logs HTTP request and response data.
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BASIC);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
You can change the log level at any time by calling setLevel
.
There are 4 levels: NONE, BASIC, HEADERS, BODY
To log to a custom location, pass a Logger
instance to the constructor.
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new
Logger() {
@Override public void log(String message) {
Log.d(TAG, "message: ");
}
});
From Gradle
compile 'com.squareup.okhttp3:logging-interceptor:(insert latest version)'
Follow this reference
EDITED: I also found this library which has a very nice structure and clean log. Try it!!
Solution 3
You can use the following class to log API calls
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
object HTTPLogger {
fun getLogger(): OkHttpClient {
/*
* OKHTTP interceptor to log all API calls
*/
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
val client = OkHttpClient.Builder()
.addInterceptor(interceptor)
.build()
return client
}
}
You can then call this class in your retrofit instance class like this
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClientInstance {
private var retrofit: Retrofit? = null
val retrofitInstance: Retrofit?
get() {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(HTTPLogger.getLogger())
.build()
}
return retrofit
}
}
The dependency required is
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
intA
Updated on August 24, 2021Comments
-
intA over 2 years
I'm using retrofit to get some data from the Flickr api. The method I'm making the call in looks like this:
public static List<String> getImageIds(int size) { Call<PhotosList> call = flickrService.getPhotos(apiKey, format, "1"); Log.d("TEMP_TAG", "photo url: " + call.request().url().toString()); photoIds = new ArrayList<String>(); call.enqueue(new Callback<PhotosList>(){ @Override public void onResponse(Call<PhotosList> call, Response<PhotosList> response) { Log.d("TEMP_TAG", "it's getting here"); PhotosList photosList = response.body(); List<Photo> photos = photosList.getPhotos().getPhoto(); for(Photo photo : photos) { Log.d("TEMP_TAG", "adding photo id to list: " + photo.getId()); photoIds.add(photo.getId()); } } @Override public void onFailure(Call<PhotosList> call, Throwable t) { // TODO: Clean up Log.d("TEMP_TAG", "photoId: "); } }); Log.d("TEMP_TAG", "it's getting here too"); return photoIds; }
However it is never getting into the
onResponse()
method. The first log statement withinonResponse()
never prints, neither does the log statement inonFailure()
. When I try entering the URL that is returned bycall.request().url().toString()
in the browser it works fine, and I get the expected JSON. Why is myenqueue()
method never firing?Thanks for any help!
-
intA over 6 yearsHmm, this doesn't seem to be doing anything for me. Used the above code and put the
HttpLoggingInterceptor
in the method making the calls, but nothing gets output. -
nhp over 6 yearsDid you add client for retrofit by using this Retrofit#client(client)?
-
intA over 6 yearsYes, I did add the
.client(client)
to the chain where I am building my Retrofit object -
nhp over 6 yearsBecause OkHttp is designed at Builder pattern, so carefully implement OkHttp with HttpLoggingInterceptor before call .build()
-
TooManyEduardos over 6 yearsYou may want to add the code of how you're initializing Retrofit, Gson, and any adapter
-
Leon over 5 yearsusing java8:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor((msg)-> { System.out.println(msg); });
-
android developer about 3 yearsThat's just logging. What about actual debugging? One with breakpoints? For some reason, getting the response-body's fields stays on "collecting data..." forever. See here: i.imgur.com/SCEL7K2.png . How could it be? What can I do to make it have the value ?
-
hsm59 over 2 yearsBased on the screenshot, the
response.body()
already shows theerrorCode
value to be0
, moreover, you can use evaluate expression to run a particular command in debug mode. You can learn more about Evaluate Expression from here