I'm trying to create a RetrofitModule
. I have an interceptor
that adds dynamic headers using a AuthHeader
object. I'm unsure how I can pass this object to the module class.
@Module
public class RetrofitModule {
private static final String TAG = "RetrofitModule";
//Do I create a constructor here for the RetrofitModule that accepts an AuthHeader object?
@Provides
@Singleton
RequestInterceptor providesRequestInterceptor(@NonNull AuthHeader authHeader) {
return new RequestInterceptor(authHeader);
}
@Provides
@Singleton
OkHttpClient.Builder provideOkHttp() {
return new OkHttpClient.Builder();
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient.Builder okHttpClient, RequestInterceptor requestInterceptor) {
okHttpClient.addInterceptor(requestInterceptor);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(
HttpLoggingInterceptor.Level.BASIC
);
okHttpClient.addInterceptor(logging);
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constants.ENDPOINT)
.client(okHttpClient.build())
.build();
}
@Provides
@Singleton
LoginService provideLoginServer(Retrofit retrofit) {
return retrofit.create(LoginService.class);
}
}
This is the AuthHeader
object I want to pass to the module so that I can add dynamic headers to the network call:
public class AuthHeader {
private String idToken;
private String idClient;
private String idEmail;
public AuthHeader(String idToken, String idClient, String idEmail) {
this.idToken = idToken;
this.idClient = idClient;
this.idEmail = idEmail;
}
public String getIdToken() {
return idToken;
}
public String getIdClient() {
return idClient;
}
public String getIdEmail() {
return idEmail;
}
}
based on your comment that you want to read the token from SharedPreferences, I provided a complete sample:
In addition to your code I've created AuthInfoProvider
that can read and provide authentication info. It's used instead of passing an AuthHeader object.
class AuthInfoProvider {
SharedPreferences preferences;
public AuthInfoProvider(Context context) {
preferences = context.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE);
}
public String getToken() {
return preferences.getString("MyToken", "");
}
}
pass the AuthInfoProvider
to interceptor:
It retrieves the token for each API call.
class RequestInterceptor implements Interceptor {
private final AuthInfoProvider provider;
public RequestInterceptor(AuthInfoProvider provider) {
this.provider = provider;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Authentication", provider.getToken())
.build();
return chain.proceed(request);
}
}
Now we should pass it to our module
@Module
public class RetrofitModule {
private static final String TAG = "RetrofitModule";
@Provides
@Singleton
public static AuthInfoProvider providesAuthInfoProvider(Context context) {
return new AuthInfoProvider(context);
}
@Provides
@Singleton
public static RequestInterceptor providesRequestInterceptor(@NonNull AuthInfoProvider authInfoProvider) {
return new RequestInterceptor(authInfoProvider);
}
// other your methods
// just make them static
}
and the component will be like:
@Singleton
@Component(modules = RetrofitModule.class)
interface NetworkComponent {
@Component.Builder
interface Builder {
Builder bindContext(@BindsInstance Context context);
NetworkComponent build();
}
void inject(SampleFragment fragment);
}
and pass context to component and build it like this:
DaggerNetworkComponent.builder()
.bindContext(getContext())
.build()
.inject(this);