Я видел тот же вопрос в стеке, но они пытаются исправить ошибку с помощью @ContributesAndroidInjector
, но в документации Dagger
говорится, что использование @ContributesAndroidInjector
необязательно, поэтому вот мои классы:
Мой MainActivityComponent
:
@Subcomponent(modules = [
MainBuilder::class
])
@ActivityScope
interface MainComponent: AndroidInjector<MainActivity>{
@Subcomponent.Factory
interface Factory: AndroidInjector.Factory<MainActivity>
}
Мой AplicationBinder
:
@Module(subcomponents = [
MainComponent::class
])
abstract class AppBuilder {
@Binds
@IntoMap
@ClassKey(MainActivity::class)
abstract fun mainActivityFactoryBind(factory: MainComponent.Factory): AndroidInjector.Factory<out Activity>
}
И мой BaseActivity
, который расширяет мой MainActivity
:
abstract class BaseActivity: HasSupportFragmentInjector, AppCompatActivity() {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return dispatchingAndroidInjector
}
}
Как я могу решить эту проблему?
На самом деле документация кинжала говорит:
Pro-tip: If your subcomponent and its factory have no other methods or supertypes other than the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you. Instead of steps 2 and 3, add an abstract module method that returns your activity, annotate it with @ContributesAndroidInjector, and specify the modules you want to install into the subcomponent. If the subcomponent needs scopes, apply the scope annotations to the method as well.
Таким образом, в основном @ContributesAndroidInjector
будет генерировать тот подкомпонент, который вы делаете вручную. Поскольку ваш случай соответствует документации Daggers
на этом шаге, вы можете свободно использовать @ContributesAndroidInjector
.
Пример:
@Singleton
@Component(
modules = [AndroidInjectionModule::class, ActivityModule::class, BroadCastReceiversModule::class,...]
)
interface AppComponent {
fun inject(pocketTreasureApplication: MyApplication)
@Component.Factory
interface Factory {
fun create(@BindsInstance application: Application): AppComponent
}
}
AndroidInjectionModule
свободен от Кинжала. В этом случае он говорит Dagger
: Эй, у нас есть компоненты Android, с которыми нужно иметь дело, и чем Dagger
знает, как их генерировать.
Затем вы должны использовать свои модули, например ActivityModule
, для создания классов, которые расширяют Activities
, Fragments
, Services
, BroadCastReceivers
и т. д.
Итак, ActivityModule hold the
@ContributesAndroidInjector`:
@Singleton
@ContributesAndroidInjector(modules = [FragmentModule::class])
abstract fun contributeMainactivity(): MainActivity
И теперь Dagger
знает, что вы можете волшебным образом внедрить зависимости в MainActivity
.
То же самое работает для FragmentModule
внутри него.
И чем в вашем MainActivity
вы можете сделать:
AndroidInjection.inject(this)
и внедрить свои зависимости.
Это все. Вы можете узнать больше в моей личной статье для Dagger-Android здесь.
Нет, модули не имеют ничего общего с фрагментами.
Если я хочу ввести свой
ViewModels
, должен быть модуль из фрагмента?