OkHttp拦截器使用OkHttpClient而没有依赖循环

Mar*_*dox 8 android dependency-injection retrofit okhttp dagger-2

我正在使用Retrofit和Dagger 2.我已经实现了一个OkHttp Interceptor来添加oauth令牌.如果没有oauth令牌或时间戳无效,我会在执行实际请求之前请求新的(通过Retrofit服务).

这会创建一个依赖循环,其中Retrofit服务需要,InterceptorInterceptor也需要Retrofit服务(用于检索oauth令牌).

示例Interceptor(为了简化它总是通过请求令牌restService#refreshAccessToken):

@Override
public Response intercept(Chain chain) throws IOException {
    Request originalRequest = chain.request();
    Request.Builder requestBuilder = originalRequest.newBuilder();

    String authHeader = "Bearer " + restService.refreshAccessToken();
    requestBuilder.addHeader("Authorization", authHeader);
    return chain.proceed(requestBuilder.build());
}
Run Code Online (Sandbox Code Playgroud)

Aus*_*ney 1

Interceptor需要将其自身注入该Interceptor#intercept()方法中。这样,您的 Retrofit 服务(包括OkHttpClient添加拦截器的服务)依赖关系就可以得到满足,而无需依赖周期。

我的NetworkComponent(提供改造服务)住在我的Application班级。这是使用 Application 注入它的示例Context

public class AuthInterceptor implements Interceptor {

    @Inject RestService restService;

    public AuthInterceptor(Context context) {
        mContext = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        // Inject Retrofit service
        ((MyApplication) context.getApplicationContext())
                .getNetworkComponent().inject(this);

        Request originalRequest = chain.request();
        Request.Builder requestBuilder = originalRequest.newBuilder();

        String authHeader = "Bearer " + restService.refreshAccessToken();
        requestBuilder.addHeader("Authorization", authHeader);
        return chain.proceed(requestBuilder.build());
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以只设置一个局部变量而不注入整个类,这样可能会获得更好的性能。

RestService restService = InjectHelper.getNetworkComponent(mContext).restService();
Run Code Online (Sandbox Code Playgroud)