Android Kotlin Retrofit多拦截器配置(含HttpLoggingInterceptor)
核心解决思路
原代码的问题是拆分了两个独立的OkHttpClient实例,分别挂载不同拦截器,而Retrofit一次只能绑定一个OkHttpClient,导致挂载在另一个实例上的HttpLoggingInterceptor完全不生效。OkHttpClient的Builder本身支持无限制挂载多个不同类型的拦截器,只需要把两类拦截器合并到同一个Client的构建链里,就能实现同时生效的效果。
配置关键注意点
- 拦截器分两种挂载方式,根据场景选择即可:
- 使用
addInterceptor()挂载的是应用拦截器,执行时机早,适合加公共请求参数、统一鉴权头等通用请求改造 - 使用
addNetworkInterceptor()挂载的是网络拦截器,紧贴真实网络请求层,适合做缓存控制、重定向拦截等链路级操作
- 使用
- 拦截器的执行顺序和代码中的添加顺序完全一致,建议把
ApiInterceptor放在日志拦截器之前添加:这样日志拦截器拿到的是已经加好api_key的最终请求,打印的日志内容和实际发出去的请求完全一致,不会出现日志缺参数的问题 - 同一个OkHttpClient.Builder可以连续调用任意多次拦截器添加方法,没有数量限制,不需要为不同拦截器单独创建Client实例
修改后的完整配置代码
import com.example.tvapptest.Network.ApiInterceptor import com.example.tvapptest.Services.MovieService import com.example.tvapptest.Services.ShowService import com.example.tvapptest.Utils.Constants import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory object RetrofitConfig { // 配置日志拦截器的打印级别 private val loggingInterceptor = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } // 合并所有拦截器到同一个OkHttpClient实例 private val sharedClient = OkHttpClient.Builder().apply { // 先添加api参数拦截器,保证后续日志能看到带参数的完整请求 addInterceptor(ApiInterceptor()) // 再添加日志拦截器 addInterceptor(loggingInterceptor) }.build() // 懒加载单例Retrofit,复用同一个OkHttpClient private val retrofit by lazy { Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(Constants.BASE_URL) .client(sharedClient) .build() } val movieService by lazy { retrofit.create(MovieService::class.java) } val showService by lazy { retrofit.create(ShowService::class.java) } }
额外适配说明
如果你的请求存在重定向场景,需要在重定向后的最终请求上也统一携带api_key,只需要把ApiInterceptor的挂载方式从addInterceptor改成addNetworkInterceptor即可,和日志拦截器的挂载逻辑完全不冲突。
内容的提问来源于stack exchange,提问作者Wassim Ben Hssen
相关产品推荐
相关产品推荐

