Ответ 1
Удалите приведенный ниже код из AppModule.class и перестройте проект
@Provides
@Singleton
Application provideContext(SomeApplication application) {
return application;
}
Я настраиваю новый модуль Android Dagger, но я получил эту ошибку Здесь мой компонент:
@AppScope
@Component(modules = {AppModule.class, NetModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(ExampleApplication application);
@BindsInstance
Builder appModule(AppModule appModule);
@BindsInstance
Builder netModule(NetModule netModule);
AppComponent build();
}
void inject(ExampleApplication __);
...
Что я создаю в моем приложении
appComponent = DaggerAppComponent
.builder()
.application(this)
.appModule(new AppModule(this))
.netModule(new NetModule())
.build()
.inject(this);
Но я все еще получаю сообщение об ошибке
Ошибка: (20, 3): @Component.Builder не имеет настроек для требуемых модулей или компонентов: [app.example.com.dagger.AppModule]
Согласно документации, которая должна быть права, что мне не хватает?
Например, это может быть действительный компонент с Builder:
@Component(modules = {BackendModule.class, FrontendModule.class})
interface MyComponent {
MyWidget myWidget();
@Component.Builder
interface Builder {
MyComponent build();
Builder backendModule(BackendModule bm);
Builder frontendModule(FrontendModule fm);
}
}
Удалите приведенный ниже код из AppModule.class и перестройте проект
@Provides
@Singleton
Application provideContext(SomeApplication application) {
return application;
}
Я думаю, что это дает более четкое объяснение использования @BindsInstance
и удаления @Provides Application
, Dagger 2 Component Builder:
@BindsInstance
Что?Вот определение:
Отмечает метод в компоненте компоновщика или компоновщика подкомпонента, который позволяет экземпляру быть привязанным к какому-либо типу внутри компонента. - источник
WHAAT? Я тоже не понимаю 😛
Вот простой намек на то, когда его использовать:
Методы @BindsInstance следует предпочитать написанию @Module с аргументами конструктора и немедленному предоставлению этих значений. - источник
Я родом из Spring Boot, а Dagger 2 - это OMG намного сложнее. :(
Так что, исходя из моего крайне ограниченного опыта работы с Dagger 2, это происходит из-за неправильной настройки *Module
с аргументом конструктора. Я до сих пор не знаю, как правильно сконфигурировать Модуль с помощью аргумента конструктора, но я скорее следую рекомендованному подходу, приведенному в документации Dagger 2, а именно: удалить аргумент конструктора и использовать вместо него @BindsInstance
и @Inject
.
например
@Module
class NetModule { // no constructor argument here!
@Inject @Named("mqttServer") // replaced by @Inject
internal lateinit var mqttServer: String
}
и в AppComponent
:
@Singleton
@Component(modules = [AndroidSupportInjectionModule::class, AppModule::class, NetModule::class, ActivityBuilder::class])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
@BindsInstance // you'll call this when setting up Dagger
fun mqttServer(@Named("mqttServer") mqttServer: String): Builder
fun build(): AppComponent
}
fun inject(app: GeoAssistantApp)
}
Затем вы предоставляете зависимости модулей при создании DaggerAppComponent
из подкласса Application
(убедитесь, что вы указали имя подкласса в AndroidManifest.xml
):
class GeoAssistantApp : Application(), HasActivityInjector, HasSupportFragmentInjector {
@Inject
internal lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
@Inject
internal lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate() {
super.onCreate()
Log.i(GeoAssistantApp::class.java.simpleName, "Initializing DaggerAppComponent...")
DaggerAppComponent.builder()
// list of modules/dependencies of modules that are part of this component need to be created here too
.application(this)
.mqttServer(getString(R.string.mqtt_server))
.build()
.inject(this)
}
override fun activityInjector(): AndroidInjector<Activity> {
return activityDispatchingAndroidInjector
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return fragmentDispatchingAndroidInjector
}
}
Обратите внимание, что Fragment
support-v4
против использования собственного Fragment
может быть источником проблем. например, для support-v4 вам нужно использовать AndroidSupportInjectionModule
, HasSupportFragmentInjector
, в то время как для native необходимо использовать AndroidInjectionModule
, HasFragmentInjector
.
В моем случае я использовал объектный модуль, поэтому мне пришлось аннотировать с помощью @JvmStatic