4

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?

I'm the man.
  • 169
  • 11
user842225
  • 4,171
  • 6
  • 42
  • 74

2 Answers2

1

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.

coroutineDispatcher
  • 5,134
  • 2
  • 16
  • 50
  • I checked the `@JvmStatic` definition https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-static/index.html , but why do we need it here if it is for static getter and setter of element, here what kind of static getter and setter are generated under the hood? – user842225 Dec 26 '19 at 12:27
  • What dependency should I have for `HttpLoggingInterceptor` ? I still get the same error. – user842225 Dec 26 '19 at 12:29
  • `com.squareup.okhttp3:logging-interceptor:4.2.1` – coroutineDispatcher Dec 26 '19 at 12:45
  • Thanks. Are you able also give an answer to my 1st question in my above comment? And I have another issue which I created another question: https://stackoverflow.com/questions/59488983/why-i-still-get-cannot-inline-bytecode-built-with-jvm-target-1-8-into-bytecode – user842225 Dec 26 '19 at 13:12
  • I'm not sure if you should use `internal` but however just place annotations just as I describe in my answer `@Provides` `@Singleton` `@JVMStatic` – coroutineDispatcher Dec 26 '19 at 13:24
0

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

Yuri Schimke
  • 8,194
  • 3
  • 23
  • 52