android - 使用Retrofit时如何动态配置OkHttpClient?

标签 android logging retrofit2 okhttp

我在我的 Android 网络应用程序中使用了 Retrofit

api "com.squareup.retrofit2:retrofit:$retrofit2Version"
api "com.squareup.retrofit2:adapter-rxjava2:$retrofit2Version"
api "com.squareup.retrofit2:converter-scalars:$retrofit2Version"
api "com.squareup.retrofit2:converter-jackson:$retrofit2Version"

在开发我的项目时,使用

记录 HTTP 请求和响应非常有用
api "com.squareup.okhttp3:logging-interceptor:$okhttp3Version"

我配置 Retrofit 如下:-

abstract class BaseService {

    internal val okHttpClient = OkHttpClient.Builder()
            .connectTimeout(OK_HTTP_CLIENT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(OK_HTTP_CLIENT_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(OK_HTTP_CLIENT_TIMEOUT, TimeUnit.SECONDS)
            .callTimeout(OK_HTTP_CLIENT_TIMEOUT, TimeUnit.SECONDS)
            .followSslRedirects(true)
            .retryOnConnectionFailure(true)
            .followRedirects(true)
            .addInterceptor(HTTP_HEADERS)
            .addInterceptor(HTTP_LOGGING_INTERCEPTOR)
            .build()

    companion object {

        private const val OK_HTTP_CLIENT_TIMEOUT: Long = 60

        private val HTTP_LOGGING_INTERCEPTOR = HttpLoggingInterceptor()
        private val HTTP_HEADERS = constructHeaderInterceptor()

        private const val HTTP_ORIGIN_HEADER = "Origin"
        private const val HTTP_ORIGIN_VALUE = "Android"

        private fun constructHeaderInterceptor(): Interceptor {
            return Interceptor {
                val request = it.request()
                val newRequest = request.newBuilder().addHeader(HTTP_ORIGIN_HEADER, HTTP_ORIGIN_VALUE).build()
                it.proceed(newRequest)
            }
        }

        init {
            HTTP_LOGGING_INTERCEPTOR.level = HttpLoggingInterceptor.Level.NONE
        }
    }
}

然后在我的服务实现中:-

class Service private constructor() : BaseService(), Api {

    private val service: Api

    init {
        val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(JacksonConverterFactory.create())
                .addConverterFactory(ScalarsConverterFactory.create())
                .build()

        service = retrofit.create(Api::class.java)
   }


    override fun query(authenticationToken: String, request: Request): Single<Response<QueryResponse>> {
        return service.query(authenticationToken, request)
    }

    companion object {

        private val BASE_URL = BuildConfig.SDK_BASE_URL

        private val INSTANCE = Service()

        fun instance(): Api {
            return INSTANCE
        }
    }
}

我面临的问题是,当我使用

HttpLoggingInterceptor.Level.BODY

logcat 输出“过多”,因为我的一些网络调用响应是非常大的 Json 文档。

我想要的是我可以在细粒度级别配置我的网络调用日志记录,例如逐个调用。

我能看到如何实现这一点的唯一方法是为每个日志记录级别创建配对的 OkHttpClientretrofit,例如BODYHEADERSBASICNONE

如果能够在逐个调用的基础上设置日志记录值,并且只使用单个 OkHttpClient & retrofit 实例,那就太棒了。

有什么方法可以按调用级别设置不同的日志记录级别?

最佳答案

您可以创建自己的记录器并委托(delegate)给 HttpLoggingInterceptor。

class MyLoggingInterceptor(private val logger: HttpLoggingInterceptor) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        if (chain.request().url().toString().contains("condition")) {
            logger.level = HttpLoggingInterceptor.Level.BODY
        } else {
            logger.level = HttpLoggingInterceptor.Level.HEADERS
        }
        return logger.intercept(chain)
    }
}

然后添加到OkHttp构建器

.addInterceptor(MyLoggingInterceptor(HttpLoggingInterceptor()))

关于android - 使用Retrofit时如何动态配置OkHttpClient?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56768451/

相关文章:

logging - log4j - 自适应日志级别 - 功能

java - 多线程日志记录的简单方法

java - 改造2:添加RequestInterceptor

android - 您能告诉我以下订阅示例有什么问题吗?

android - Android Espresso 包 `android.support.test.espresso.intent` 的依赖项是什么?

android - 无法在 Android 模拟器 - Windows 上运行 React-Native 应用程序

使用 dictConfig 进行 Python 日志记录,使用两个流处理程序以不同的消息级别发布到 stdout 和 stderr

android - AndEngine - 如何创建一个按钮?

java - 如何在启动完成时发送通知?

java - 使用 POJO 类关闭 response.body()