Je configure le nouveau poignard Android mais j'ai eu cette erreur. Voici mon composant:
@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 __);
...
Que je construis comme ça dans mon application
appComponent = DaggerAppComponent
.builder()
.application(this)
.appModule(new AppModule(this))
.netModule(new NetModule())
.build()
.inject(this);
Mais je reçois toujours l'erreur
Erreur: (20, 3) erreur: @ Component.Builder manque des paramètres pour les modules ou composants requis: [app.example.com.dagger.AppModule]
Selon la documentation qui devrait être exacte, qu'est-ce qui me manque?
Par exemple, cela pourrait être un composant valide avec un générateur:
@Component(modules = {BackendModule.class, FrontendModule.class})
interface MyComponent {
MyWidget myWidget();
@Component.Builder
interface Builder {
MyComponent build();
Builder backendModule(BackendModule bm);
Builder frontendModule(FrontendModule fm);
}
}
Supprimez le code ci-dessous de AppModule.class et reconstruisez le projet.
@Provides
@Singleton
Application provideContext(SomeApplication application) {
return application;
}
Je pense que cela fournit une explication un peu plus claire sur l'utilisation de @BindsInstance
et suppression de @Provides Application
, Générateur de composants de poignard 2 :
@BindsInstance
Quoi?Voici la définition:
Marque une méthode sur un générateur de composant ou un générateur de sous-composant qui permet de lier une instance à un type quelconque du composant. - la source
QUOI? Je ne le comprends pas non plus ????
Voici un indice simple pour savoir quand l'utiliser:
Les méthodes @BindsInstance doivent être préférées à l'écriture d'un @Module avec des arguments de constructeur et à la fourniture immédiate de ces valeurs. - la source
Je viens de Spring Boot et Dagger 2 est OMG tellement plus compliqué. :(
Donc, basé sur mon expérience extrêmement limitée avec Dagger 2, cela se produit car il y a un *Module
avec un argument constructeur mal configuré. Je ne sais toujours pas comment configurer correctement le module avec un argument de constructeur, mais je vais plutôt suivre l'approche recommandée dans la documentation de Dagger 2, à savoir supprimer le ou les arguments de constructeur et utiliser @BindsInstance
et @Inject
au lieu.
par exemple.
@Module
class NetModule { // no constructor argument here!
@Inject @Named("mqttServer") // replaced by @Inject
internal lateinit var mqttServer: String
}
et dans 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)
}
Ensuite, vous fournissez les dépendances des modules lors de la construction de DaggerAppComponent
à partir de la sous-classe Application
(assurez-vous que vous spécifiez le nom de la sous-classe dans 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
}
}
Notez que le support-v4
Fragment
vs natif Fragment
L'utilisation peut être une source de problèmes. par exemple. pour support-v4, vous devez utiliser AndroidSupportInjectionModule
, HasSupportFragmentInjector
, tandis qu'avec natif, vous devez utiliser AndroidInjectionModule
, HasFragmentInjector
.
Dans mon cas, j'utilisais un objet module, alors je devais annoter avec @JvmStatic