i recently used from New Android Injector with Dagger 2 in my project and i have an issue : i want provide a dynamic String with dagger and i don't know how do this; i receive a token from server and need to pass this as field to and instance of OkHttp3CookieHelper; how should i do this ?
i tried to pass this String into Module Constructor but i think this is not true! i think maybe should use from @BindsInstance !! please help ;)
this is my AppModule :
@Module(subcomponents = {MainActivityComponent.class})
public class AppModule {
private String cookie ;
public AppModule(String Cookie){
this.cookie = Cookie;
}
@Singleton
@Provides
Context provideContext(Application application) {
return application;
}
@Singleton
@Provides
OkHttp3CookieHelper provideCookie(@Named("baseURL") String baseURL,
@Named("csrfToken") String csrfToken) {
OkHttp3CookieHelper cookieHelper = new OkHttp3CookieHelper();
cookieHelper.setCookie(baseURL, csrfToken, cookie);
return cookieHelper;
}
@Singleton
@Provides
OkHttpClient.Builder provideOkHttp(HttpLoggingInterceptor interceptor,
OkHttp3CookieHelper cookieHelper) {
final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout(8, TimeUnit.SECONDS);
httpClient.readTimeout(8, TimeUnit.SECONDS);
httpClient.callTimeout(8, TimeUnit.SECONDS);
httpClient.cookieJar(cookieHelper.cookieJar());
httpClient.addInterceptor(interceptor);
return httpClient;
}
@Singleton
@Provides
HttpLoggingInterceptor provideHttpInterceptor() {
final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return interceptor;
}
@Singleton
@Provides
GsonConverterFactory provideGsonConverterFactory() {
return GsonConverterFactory.create();
}
@Singleton
@Provides
@Named("baseURL")
String provideBaseURL() {
return Const.BASE_URL;
}
@Singleton
@Provides
@Named("csrfToken")
String provideCrfToken() {
return Const.CRF_TOKEN;
}
@Singleton
@Provides
Api provideApi(Retrofit retrofit) {
return retrofit.create(Api.class);
}
@Singleton
@Provides
Retrofit provideRetrofit(GsonConverterFactory converterFactory, OkHttpClient.Builder httpClient,
@Named("baseURL") String baseURL) {
return new Retrofit.Builder().baseUrl(baseURL)
.addConverterFactory(converterFactory)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(httpClient.build())
.build();
}
@Singleton
@Provides
SharedPreferences provideSharedPreference(Context context) {
return context.getSharedPreferences("myShp", Context.MODE_PRIVATE);
}
//and this is my AppComponent :
@Singleton
@Component(modules = {AndroidInjectionModule.class, ActivityBuilder.class, AppModule.class,
ViewModelFactoryModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
void inject(App app);
}
finally and after about 10 hours searching and read some articles i solved my issue:D
NOTICE !
no need to pass your response token by yourself also no need to bind dependency(in this case response token)into AppComponent but if u want to do this u can use @Component.Builder or @Component.Factory that u can use this useful article : Dagger2: @Component.Factory and @SubComponent.Factory
first should add this dependency to app.gradle file :
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
then provide instance of PersistentCookieJar in appMoule class and pass to our OkHttpClient instance:
@Singleton
@Provides
PersistentCookieJar ProvideCookieJar(Context context) {
return new PersistentCookieJar(new SetCookieCache(),
new SharedPrefsCookiePersistor(context));
}
@Singleton
@Provides
OkHttpClient.Builder provideOkHttp(HttpLoggingInterceptor interceptor,
PersistentCookieJar persistentCookieJar) {
final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout(8, TimeUnit.SECONDS);
httpClient.readTimeout(8, TimeUnit.SECONDS);
httpClient.callTimeout(8, TimeUnit.SECONDS);
httpClient.cookieJar(persistentCookieJar);
httpClient.addInterceptor(interceptor);
return httpClient;
}
don't forget to provide Context that need to create PersistentCookieJar instance :
@Provides
@Singleton
Context provideContext(Application application) {
return application;
}
and in your Appication class should bind your application class :
DaggerAppComponent.builder()
.application(this)
.build()
.inject(this);
and your AppComponent Shoud be like this :
@Singleton
@Component(modules = {AndroidInjectionModule.class, ActivityBuilder.class,
AppModule.class, ViewModelFactoryModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
void inject(App app);
}
OK every thing Done ! now your request contain cookie and successfully can get server Response :)