Модернизация кинжала не может быть предоставлена

К сожалению, Dagger - это круто, и я пытаюсь внедрить его дооснащение. Я ввел Context и SharedPreferences, и он работает нормально, но Retrofit сломал все это. Он распознает класс DaggerRetrofitComponent, но не находит DaggerAppComponent.

Модуль модернизации:

@Module
public class RetrofitModule {
    public static final String BASE_URL = "http://api.themoviedb.org/3/";
    @Provides
    HttpLoggingInterceptor getHttpLoggingInterceptor(){
        return new HttpLoggingInterceptor();

    }
    @Provides
    OkHttpClient getOkHttpClient(HttpLoggingInterceptor interceptor){
        return new OkHttpClient.Builder().addInterceptor(interceptor).build();
    }
    @Provides
    GsonConverterFactory getGsonConverterFactory(){
        return GsonConverterFactory.create();
    }
    @Provides
    Retrofit getRetrofit(GsonConverterFactory gsonConverterFactory, OkHttpClient client){
        return new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(gsonConverterFactory)
                .client(client).build();
    }
}

Заявление:

public class MyApplication extends Application {
    private static AppComponent appComponent;
    public static AppComponent getAppComponent(){
        return appComponent;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        appComponent=buildComponent();

    }


    protected AppComponent buildComponent(){
        if (BuildConfig.DEBUG){
            Timber.plant(new Timber.DebugTree());
        }

        return DaggerAppComponent.builder().sharedPreferenceModule(new SharedPreferenceModule()).contextModule(new ContextModule(this)).build();


    }
}

AppComponent:

@Singleton
@Component(modules = {ContextModule.class, SharedPreferenceModule.class})
public interface AppComponent {
    void inject(MainActivity mainActivity);
}

Компонент модернизации:

@Singleton
@Component(modules = {RetrofitModule.class})
public interface RetrofitComponent {
    void injectRetrofit(Activity activity);
//
}

Основная деятельность:

public class MainActivity extends AppCompatActivity {
    @Inject
    Context context;
    @Inject
    SharedPreferences sharedPreferences;
    @Inject
    Retrofit retrofit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerRetrofitComponent.builder().retrofitModule(new RetrofitModule()).build().injectRetrofit(this);
        MyApplication.getAppComponent().inject(this);


    }
}
0
0
687
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Dagger 2 не позволяет вводить зависимости от нескольких компонентов. Вам следует подумать об использовании подкомпонентов.

https://google.github.io/dagger/subcomponents.html

UPD: Я бы посоветовал вам создать подкомпонент, производный от вашего AppComponent, например NetComponent. А затем укажите getNetComponent.inject () в своей деятельности. Поскольку NetComponent будет производным от AppComponent, он предоставит все зависимости от appComponent, которые вам нужны.

Это немного сложнее, но это правильный способ сделать это, также вы должны узнать о Dagger Scopes.

ИЛИ ЖЕ

Быстрый способ - просто поместить ваши сетевые зависимости в AppComponent.

Я не уверен, почему вы хотите модифицировать компонент (модуля из вашего компонента приложения должно быть достаточно), тогда вы должны использовать последнюю версию Dagger для обработки автоматической инъекции для представлений вашего контроллера (действий и фрагментов)

@Singleton
@Component(modules = [ApplicationModule::class])
interface ApplicationComponent : AndroidInjector<MyApplication>
{
    override fun inject(application: MyApplication)

    @Component.Builder
    interface Builder
    {
        @BindsInstance
        fun application(application: MyApplication): Builder

        fun build(): ApplicationComponent
    }
}

__

@Module(includes = [AndroidSupportInjectionModule::class,ActivityBuilderModule::class, NetworkModule::class])
abstract class ApplicationModule
{
    @Binds
    @Singleton
    abstract fun bindApplication(application: MyApplication): Application

    @Module
    companion object
    {
        @Provides
        @Singleton
        @ApplicationContext
        @JvmStatic
        fun provideApplicationContext(application: MyApplication): Context = application
    }
}

__

@Module
abstract class ActivityBuilderModule
{
    @ContributesAndroidInjector(modules = [MainActivityModule::class])
    @ActivityScope
    abstract fun contributeMainActivity(): MainActivity

    //others activities there
}

@Module
object NetworkModule
{
    // For simplicity just retrofit provider, but all others network resources should be here of course

    @Provides
    @Singleton
    @JvmStatic
    fun provideRetrofit(rxJava2CallAdapterFactory: RxJava2CallAdapterFactory,
                        nullOrEmptyConverterFactory: Converter.Factory,
                        @ApplicationContext okHttpClient: OkHttpClient,
                        gsonConverterFactory: GsonConverterFactory): Retrofit =
        Retrofit.Builder()
            .addCallAdapterFactory(rxJava2CallAdapterFactory)
            .addConverterFactory(nullOrEmptyConverterFactory)
            .addConverterFactory(gsonConverterFactory)
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .build()
}

__

class MyApplication : DaggerApplication()
{
    private val applicationInjector = DaggerApplicationComponent.builder()
        .application(this)
        .build()

    public override fun applicationInjector() = applicationInjector
}

__

Затем из ваших действий / фрагментов сделайте их унаследованными от DaggerActivity или DaggerFragment, и вы сможете делать свои инъекции из коробки.

Вы можете взглянуть на мой шаблонный проект https://github.com/SamYStudiO/beaver, он может помочь.

ps: Извините, это все kotlin, но его легко конвертировать в java

Котлин не является проблемой, но я еще не изучал большинство этих аннотаций, таких как JVMstatic.

Bissi singh 10.03.2018 13:33

Что такое ActivityBuilderModule?

Bissi singh 10.03.2018 14:06

Я добавил его (полезно создавать подкомпоненты действий из компонента приложения), проверьте мою ссылку github внизу, если вы что-то пропустили, все исходит из этого

Samuel Eminet 10.03.2018 14:18

@JvmStatic - это просто аннотация, чтобы сообщить java, что это статический метод, поскольку kotlin не является статическим ключевым словом

Samuel Eminet 10.03.2018 14:23

MainActivityModule? Кажется, я не могу найти его в репозитории github

Bissi singh 10.03.2018 14:36

Вот он: github.com/SamYStudiO/beaver/blob/master/app/src/main/kotlin‌ /…, если у вас есть определенные зависимости с вашим MainActivity, то куда их поместить.

Samuel Eminet 10.03.2018 14:53

Аннотации не допускаются перед сопутствующим объектом в модуле приложения. Я заменил сопутствующий объект статическим блоком.

Bissi singh 10.03.2018 15:10

Предназначен для преобразования в java, для каждого сопутствующего блока вы должны удалить их, удалить @JvmStatic и сделать метод статическим

Samuel Eminet 10.03.2018 15:14

Извините, это слишком сложно для меня как новичка, который только что узнал о модулях и поставках

Bissi singh 11.03.2018 03:46
Ответ принят как подходящий

Удалите этот класс:

//@Singleton
//@Component(modules = {RetrofitModule.class})
//public interface RetrofitComponent {
//    void injectRetrofit(Activity activity);
//
//}

и изменим AppComponent:

@Singleton
@Component(modules = {ContextModule.class, SharedPreferenceModule.class, RetrofitModule.class})
public interface AppComponent {
    void inject(MainActivity mainActivity);
}

Это работает, но как разделить зависимости уровня приложения и уровня активности?

Bissi singh 10.03.2018 15:42

Модернизация не является зависимостью от уровня активности, она помечена @Singleton.

EpicPandaForce 10.03.2018 16:34

Да, я понял. Но не могли бы вы привести пример зависимостей на уровне активности (не обязательно дооснащение).

Bissi singh 10.03.2018 16:36

@Bissisingh, ваш докладчик для вашей деятельности, является примером зависимости в области действия.

mt0s 10.03.2018 19:41

@ mt0s Но могу ли я ввести ведущего, например, кроме того факта, что я могу сбрасывать все на уровне приложения, что не кажется хорошим.

Bissi singh 11.03.2018 03:47

Другие вопросы по теме