【问题标题】:Two questions about providing instance of HttpLoggingInterceptor for OkHttpClient in Dagger 2 moduleDagger 2模块中为OkHttpClient提供HttpLoggingInterceptor实例的两个问题
【发布时间】:2020-04-16 07:39:00
【问题描述】:

我正在使用 Kotlin 和 Dagger 2 开发一个 Android 项目。我有一个 NetworkModule,它应该提供一个 Retrofit 的单例实例。我在其中定义了所有这些提供程序功能。

下面的所有代码 sn-p 都在 NetworkModule 内:

@Module
object NetworkModule {
   ...
}

我的第一个问题:

我想为OkHttpClient 提供HttpLoggingInterceptor 的单例。这是我尝试过的:

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

但我得到一个编译错误:Unresolved reference 'setLevel' 和Unresolved reference 'Level',如何摆脱它?

我的第二个问题:

我将 OkHttpClient 提供程序函数定义为:

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

我怎样才能使它在调试模型中只有addInterceptor(loggingInterceptor),而在发布模式下不在上述提供程序函数中添加HttpLoggingInterceptor?

【问题讨论】:

    标签: android retrofit2 dagger-2 okhttp retrofit2.6


    【解决方案1】:

    对于你的第一个问题,你确定你有正确的依赖关系吗?

    或者既然你在 Kotlin,试试这样:

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

    第二个问题:

    我怎样才能做到只有 addInterceptor(loggingInterceptor) 时 它在调试模型中,而在发布模式中不添加 上面的provider函数中的HttpLoggingInterceptor?

    @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()
    }
    

    注意@JvmStatic 和@Singleton 注释,因为您使用的是单例。一个用于 JVM,另一个用于范围。

    【讨论】:

    • 我检查了 @JvmStatic 定义 kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-static/… ,但是如果它是用于元素的静态 getter 和 setter 为什么我们需要它,这里会生成什么样的静态 getter 和 setter ?
    • HttpLoggingInterceptor 应该有什么依赖关系?我仍然遇到同样的错误。
    • com.squareup.okhttp3:logging-interceptor:4.2.1
    • 谢谢。您是否也可以在我的上述评论中回答我的第一个问题?我还有另一个问题,我创建了另一个问题:stackoverflow.com/questions/59488983/…
    • 我不确定您是否应该使用internal,但只需按照我在回答@Provides @Singleton @JVMStatic 中描述的方式放置注释即可
    【解决方案2】:

    对于仅在 DEBUG 构建中设置记录器,您有两个选项

    1. 使用基于 Build.DEBUG 的 NONE 级别

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

    HttpLoggingInterceptor l = ...;
    
    if (!BuildConfig.DEBUG) {
        l.level(HttpLoggingInterceptor.Level.NONE);
    }
    
    1. 使用 Dagger 可选/可为空来避免设置拦截器

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      相关资源
      最近更新 更多