Внедрение зависимостей только для базовой активности приводит к сбою дочерней активности

1

У меня есть BaseActivity, которая расширена несколькими действиями. У меня есть требование ввести объект (InputProvider.java) в BaseActivity, но это не требуется в его дочерних действиях.

@Subcomponent
public interface BaseActivityInjector extends AndroidInjector<BaseActivity> {
  @Subcomponent.Builder
  abstract class Builder extends AndroidInjector.Builder<BaseActivity> {}
}

@Module(
  includes = {
    AppModule.class,
    AndroidSupportInjectionModule.class,
    InitializerModule.class},
  subcomponents = {
     BaseActivityInjector.class
  })
public abstract class AppInjectionModule {
  @Binds
  @IntoMap
  @ActivityKey(BaseActivity.class)
  abstract AndroidInjector.Factory<? extends Activity> bindBaseActivityInjectorFactory(BaseActivityInjector.Builder builder);
}

@Module
public class InitializerModule {
  @Provides
  public InputProvider getInputProvider() {
    return new InputProviderImpl();
  }
}

public abstract class BaseActivity extends FragmentActivity {
@Inject
InputProvider inputProvider;

    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
    }
}

Когда я запускаю свое приложение, оно падает на самом первом экране (заставке), который также расширяет BaseActivity, со следующим сообщением:

Невозможно запустить действие ComponentInfo {com.app.mobile.android.dev/com.app.mobile.android.SplashScreen}: java.lang.IllegalArgumentException: фабрика инжектора не привязана к классу. Заводы по производству инжекторов были связаны с супертипами com.delta.mobile.android.SplashScreen: [com.app.mobile.android.uikit.view.BaseActivity]. Вы хотели связать фабрику инжекторов для этого подтипа?

Журнал ошибок указывает на AndroidInjection.inject(this); в BaseActivity через SplashScreen.

Теги:
dependency-injection
dagger-2

1 ответ

1

AndroidInjection ищет правильный компонент для вашей деятельности по типу. Если вы попытаетесь внедрить SplashScreen и он не сможет найти компонент, зарегистрированный для SplashScreen то он выдаст исключение.

Если вы хотите внедрить только BaseActivity но не BaseActivity вы не можете использовать AndroidInjection для этого. Вам придется создать компонент самостоятельно и таким образом внедрить свою активность.

В качестве альтернативы вы не можете расширять BaseActivity или объявлять компонент для каждого действия и использовать AndroidInjection по назначению. Если вы внедрите дочернее действие, оно также внедрит поля в родительском.

  • 0
    Если вы используете базовый модуль для BaseActivity и несколько компонентов для каждого действия, знаете ли вы, как ссылаться на действие в базовом модуле? Fun предоставляетPackageManager (Activity: BaseActivity): PackageManager = activity.packageManager. Если это предусмотрено в BaseModule, кинжал не может найти BaseActivity и является базовым модулем, я не могу предоставить конкретный экземпляр действия.
  • 0
    @Vairavan текущая (единственная) опция - привязать каждый дочерний элемент как базовый тип в модуле (или компоновщик компонентов ... в этом случае вы также не можете использовать dagger.android). Была идея добавить способ связывать типы с dagger.android, но я не думаю, что это будет реализовано в ближайшее время
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню