【问题标题】:How to provide 2 Retrofit interfaces width different levels of logging?如何提供 2 个 Retrofit 接口宽度不同级别的日志记录?
【发布时间】:2017-11-23 23:16:30
【问题描述】:

我关心的是应该打印多少 OkHttp 日志。
在我的应用程序的某些屏幕上,有太多的 API 调用 --> logcat 被淹没了,所以我想限制/关闭那里的日志记录,除了一次性调试

我是 Dagger 2 和依赖注入的新手,一直关注 this tutorial

我有以下工作,但我不确定那里是否有任何不好的做法,或者是否可以进一步改进:
(我的应用中有大约 20 个 Retrofit API 接口/ 20 个不同的端点)

@Module
public class NetModule {

    private String mBaseUrl;
    private final HttpLoggingInterceptor LOGGING_FULL = new HttpLoggingInterceptor().setLevel
        (HttpLoggingInterceptor
                .Level.BODY);
private final HttpLoggingInterceptor LOGGING_HEADERS = new HttpLoggingInterceptor().setLevel
        (HttpLoggingInterceptor
                .Level.HEADERS);

    // Constructor needs one parameter to instantiate.
    public NetModule(String baseUrl) {
        this.mBaseUrl = baseUrl;
    }

    @Provides
    @Singleton
    OkHttpClient.Builder provideOkHttpClientBuilder() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //...
        return builder;
    }

    @Provides
    @Singleton
    Retrofit.Builder provideRetrofitBuilder() {
        return new Retrofit.Builder()
                .baseUrl(mBaseUrl);
    }

    @Provides
    @Singleton
    Api1 provideApi1(OkHttpClient.Builder okHttpClientBuilder, Retrofit.Builder retrofitBuilder) {
        if (BuildConfig.DEBUG || !BuildConfig.FLAVOR.equals(FLAVOUR_PRODUCTION)) {
            okHttpClientBuilder.addInterceptor(LOGGING_HEADERS);
        }
        return retrofitBuilder.client(okHttpClientBuilder.build()).build().create(Api1.class);
    }
    @Provides
    @Named("logging_full")
    @Singleton
    Api1 provideApi1FullLog(OkHttpClient.Builder okHttpClientBuilder, Retrofit.Builder retrofitBuilder) {
        if (BuildConfig.DEBUG || !BuildConfig.FLAVOR.equals(FLAVOUR_PRODUCTION)) {
            okHttpClientBuilder.addInterceptor(LOGGING_FULL);
        }
        return retrofitBuilder.client(okHttpClientBuilder.build()).build().create(Api1.class);
    }
    //... Repeats for Api2, Api3, ..., Api20

}

用法:
1) 在大多数情况下,不需要记录正文,因此:

@Inject
Api1 api1;

2) 在某些情况下,日志主体是必需的:

@Inject
@Named("logging_full")
Api1 api2;

【问题讨论】:

    标签: android retrofit2 dagger-2 okhttp3


    【解决方案1】:

    我认为这是一个过度设计的解决方案。如果您在 http 拦截器层需要不同的行为,则不必处理不同的 Api、httpclients 或其他任何实例。

    这将是我解决您的问题的第一种方法。

    1) 对 Api 使用单个实例,对 OkHttpClient 使用单个实例(没有多个 Dagger 提供程序)

    2) 有一个用于调试的拦截器,没有用于生产的拦截器。这样可以避免 if( Build.DEBUG ) 逻辑。

    3) 为每个端点添加一个自定义标头

       interface YourApi {
    
          @Headers("YourCustomLoggingHeader: HEADERS")
          @GET("/your_path")
          ReturnType yourApiMethod( ParamType p);
       }
    

    4) 如果拦截器被注入(调试构建),则检查拦截方法中的标头并相应记录。

        @Override public Response intercept(Chain chain) throws IOException {
    
             String headerValue = chain.request().headers().get("YourCustomLoggingHeader");
    
             if( TextUtils.isEmpty(headervalue)){
                return = chain.proceed(request);
             }
    
             // TODO remove header for real request
    
             switch( headerValue ){
               case "HEADERS":
                    //TODO log headers 
                    break;
               case "BODY":
                    //TODO log body 
                    break;
             }
        }
    

    这是伪代码,因为我不在 IDE 上。

    【讨论】:

    • 感谢@RobertEstivill,但您也错过了重点:) 我不关心包含/排除 HTTP 标头。我关心的是应该打印多少 OkHttp 日志。在某些屏幕上,API 调用太多了 --> logcat 被淹没了,所以我想限制/关闭那里的日志记录,除了一次性调试
    • 标头用作每个/端点配置。当然,您也可以将日志记录行为基于所有请求属性(例如:路径)。但是拥有一个外部配置的属性是一个更明显的选择。如果您需要在运行时更改行为,那么您将不得不保留 HttpLogginInterceptor 实例并修改它的状态,以便它在调用之间的行为不同
    猜你喜欢
    • 2016-07-11
    • 2012-02-08
    • 2013-03-26
    • 2017-01-31
    • 2020-12-25
    • 2022-10-14
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多