Как обеспечить Dynami c String, такие как (ответ сервера) в модуле? - PullRequest
2 голосов
/ 01 марта 2020

Я недавно использовал Новый Android Инжектор с Dagger 2 в моем проекте, и у меня возникла проблема: я хочу предоставить динамическую c строку с кинжалом, и я не знаю, как это сделать ; я получаю токен с сервера и должен передать его как поле и экземпляр OkHttp3CookieHelper ; Как мне это сделать?

Я пытался передать эту строку в конструктор модулей, но я думаю, что это не так! я думаю, может быть, следует использовать из @BindsInstance! пожалуйста, помогите;)

это мой 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);
}

проблема: кинжал не может создать экземпляр из AppModule!

1 Ответ

2 голосов
/ 03 марта 2020

наконец, и после примерно 10 часов поиска и прочтения некоторых статей я решил свою проблему: D

УВЕДОМЛЕНИЕ!

не нужно также передавать свой токен ответа самостоятельно нет необходимости связывать зависимость (в данном случае токен ответа) в AppComponent, но если вы хотите сделать это, вы можете использовать @ Component.Builder или @ Component.Factory, чтобы вы могли использовать эту полезную статью: Dagger2: @ Component.Factory и @ SubComponent.Factory

Но для решения проблемы:

сначала следует добавить эту зависимость в файл app.gradle:

implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'

, а затем предоставить экземпляр PersistentCookieJar в классе appMoule и перейдите к нашему OkHttpClient экземпляру:

@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;
}

не забудьте предоставить Context, который необходим для создания экземпляра PersistentCookieJar:

@Provides
@Singleton
Context provideContext(Application application) {
    return application;
}

и в вашем классе Appication должны быть привязаны класс вашего приложения:

DaggerAppComponent.builder()
                      .application(this)
                      .build()
                      .inject(this);

, и ваш 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);
}

OK, все готово! Теперь ваш запрос содержит cook ie и успешно может получить ответ сервера:)

...