Two questions about providing instance of HttpLoggingInterceptor for OkHttpClient in Dagger 2 module

958 Views Asked by At

I am developing an Android project with Kotlin and Dagger 2. I have a NetworkModule it is supposed to provide a singleton instance of Retrofit. in which I define all those provider functions.

All code snippet below are inside NetworkModule :

@Module
object NetworkModule {
   ...
}

My 1st question:

I want to provide a singleton of HttpLoggingInterceptor for OkHttpClient. Here is what I tried:

@Provides
internal fun provideLoggingInterceptor(): Interceptor {
    // compiler error: Unresolved reference 'setLevel', unresolved reference 'Level'
    return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}

But I get a compilation error: Unresolved reference 'setLevel' and Unresolved reference 'Level', How to get rid of it?

My 2nd question:

I define my OkHttpClient provider function as:

@Provides
internal fun provideOkHttpClient(loggingInterceptor: Interceptor): OkHttpClient {
        return OkHttpClient.Builder()
                        .addInterceptor(loggingInterceptor)
                        ...
                        .build()
}

How can I make it so that only addInterceptor(loggingInterceptor) when it is in the debug model, whereas in release mode not add the HttpLoggingInterceptor in the above provider function?

2

There are 2 best solutions below

5
On BEST ANSWER

For your first question, are you sure you have the right dependencies?

Or since you are in Kotlin, try it like this:

@JvmStatic
@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
    val httpLoggingInterceptor = HttpLoggingInterceptor()
    httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
    return httpLoggingInterceptor
}

For you second question:

How can I make it so that only addInterceptor(loggingInterceptor) when it is in the debug model, whereas in release mode not add the HttpLoggingInterceptor in the above provider function?

@Provides
@JvmStatic
@Singleton
fun provideOkHttpClient(interceptor: Interceptor): OkHttpClient{
 val okhttpBuilder = OkHttpClient.Builder() //and every other method after it except build() would return a Builder (Builder pattern)
 if(BuildConfig.DEBUG){
  okHttpBuilder.addInterceptor(interceptor)
 }
 return okHttpBuilder.build()
}

Notice the @JvmStatic and @Singleton annotations since you are using Singletons. One is for the JVM and the other for scoping.

0
On

For setting the logger only in DEBUG builds you have two options

  1. Use the NONE level based on Build.DEBUG

https://stackoverflow.com/a/23844716/1542667

HttpLoggingInterceptor l = ...;

if (!BuildConfig.DEBUG) {
    l.level(HttpLoggingInterceptor.Level.NONE);
}
  1. Use Dagger optional/nullable to avoid setting the interceptor

https://medium.com/@birajdpatel/avoid-nullable-dependencies-in-dagger2-with-bindsoptionalof-c3ad8a8fde2c