如何在Retrofit 2(Android)中动态设置标题列表

p-p*_*-ni 5 android retrofit retrofit2

我们正在尝试迁移到使用Retrofit2,而我遇到的问题是我们需要为每个请求传递一组动态生成的标头(用于分析).

参数级别不支持@Headers,因为标题字段名称因当前活动而异,所以我不能使用@Header.

有没有办法在execute()之前追加标题?(寻找与@ QueryMap/@ FieldMap类似的东西,但是对于标题)

注意:初始化客户端时我没有头文件列表(因此不能使用Interceptor执行此操作).

Lov*_*vis 2

您仍然可以(并且必须)使用拦截器。
您所需要的只是一点架构。

首先创建一个提供必要标头的帮助程序。

public class AnalyticsHeader {
 private String analyticsHeaderName;
 private String analyticsHeaderValue;

 public void setHeaderValue(String header) {
   this.analyticsHeaderValue = header;
 } 

 public void setHeaderName(String header) {
   this.analyticsHeaderName = header;
 } 

 public String getHeaderName() { 
  return analyticsHeaderName;
 }
 public String getHeaderValue() { 
  return analyticsHeaderValue;
 }
}
Run Code Online (Sandbox Code Playgroud)

将此类的实例保留在应用程序内可访问的位置,例如应用程序的 MainActivity(或者更好的是,使用依赖注入)

现在,创建拦截器后,只需将 AnalyticsHeader 的实例传递到拦截器中即可:

public static final class AnalyticsInterceptor implements Interceptor {
        private final AnalyticsHeader header;

        public AnalyticsInterceptor(AnalyticsHeader header) {
            this.header = header;
        }

        @Override
        public Response intercept(Chain chain) throws IOException {
            final Request original = chain.request();
            Response response;
            if (header.getHeader() != null) {
                 Request request = original.newBuilder()
                        .header(header.getHeaderName(), header.getHeaderValue())
                        .method(original.method(), original.body())
                        .build();
                 response = chain.proceed(request);
            } else {
                response = chain.proceed(original);
            }

         return response;
       }
 }
Run Code Online (Sandbox Code Playgroud)

进而...

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new AnalyticsInterceptor(CentralPlaceInApp.getAnalyticsHeader());
...
retrofit = new Retrofit.Builder()
                .baseUrl(config.getRestUrl())
                .client(builder.build())
                .build();
Run Code Online (Sandbox Code Playgroud)

现在,您可以在应用程序运行时随时使用以下命令更改标头的值CentralPlaceInApp.getAnalyticsHeader().setHeaderValue(CurrentActivity.class.getSimpleName());