Retrofit无法更新请求Header中新Token问题求助
问题根源分析
哥们,你的问题出在Retrofit单例的初始化逻辑和Token的绑定方式上!核心原因是:第一次创建Retrofit实例时,拦截器就把当时传入的Token固定下来了。因为你的RetrofitClient是单例模式,只要retrofit不为null就直接返回旧实例,后续即使传入新Token,旧拦截器里捕获的还是最初的Token值,自然不会更新。
另外还有个容易忽略的小错误:你直接用new OkHttpClient()然后添加拦截器的方式是错的——OkHttpClient是不可变类,必须通过Builder构建才能让拦截器正确生效。
解决方案
1. 让拦截器动态读取最新Token
把拦截器里的Token从传入参数改成每次请求时从SharedPreferences实时获取,这样不管Token什么时候更新,请求都会用最新的值。
2. 修复OkHttpClient的构建方式
改用OkHttpClient.Builder来创建客户端,确保拦截器能被正确添加并生效。
3. 可选:添加重置Retrofit实例的方法
虽然动态读取Token已经能解决核心问题,但添加一个重置方法可以在Token更新时强制重建客户端,让逻辑更严谨。
修改后的代码
RetrofitClient 代码
public class RetrofitClient { private static Retrofit retrofit = null; // 去掉token参数,拦截器会动态从SharedPreferences获取 public static Retrofit getClient() { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); // 用Builder构建OkHttpClient,这才是正确的姿势 OkHttpClient okClient = new OkHttpClient.Builder() .addInterceptor(chain -> { Request original = chain.request(); // 每次请求都实时获取最新Token String token = AuthUser.getInstance().getToken(); // 替换成你获取Token的实际方式 Request request = original.newBuilder() .header(Config.X_AUTH_TOKEN, "Bearer " + token) .method(original.method(), original.body()) .build(); Log.d("Authorization", token); return chain.proceed(request); }) .addInterceptor(logging) .build(); if (retrofit == null) { Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") .create(); retrofit = new Retrofit.Builder() .baseUrl(Config.BASE_URL1) .client(okClient) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); } return retrofit; } // 新增:Token更新时调用,清空旧的Retrofit实例(可选,动态读取Token生效后可省略) public static void resetClient() { retrofit = null; } }
登录成功后的调用示例
// 保存新Token到SharedPreferences authUser.setToken(newToken); // 可选:重置Retrofit客户端,下次请求会重建实例 RetrofitClient.resetClient();
为什么这样能解决问题?
- 拦截器不再依赖固定的传入Token,而是每次请求都从SharedPreferences读取最新值,确保Token实时生效。
- 用
OkHttpClient.Builder构建客户端,保证拦截器被正确添加并作用于所有请求。 - 可选的
resetClient()方法可以在Token变更后强制重建Retrofit实例,避免任何潜在的缓存问题。
内容的提问来源于stack exchange,提问作者Lending Square
相关产品推荐
相关产品推荐

