Je suis nouveau en utilisant Dagger2 (j'ai toujours utilisé Koin) et j'essaie d'implémenter un échantillon simple mais je ne sais pas vraiment ce qu'il me manque. C'est ce que j'ai obtenu jusqu'à présent.
app.gradle :
class MainActivity : AppCompatActivity() {
@Inject
lateinit var testClass: TestClass
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onResume() {
super.onResume()
val x = testClass.getRandomValueFromCTest()
}
}
AppModule.kt : p>
class App : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().application(this@App).build()
}
}
AppComponent.kt :
class TestClass @Inject constructor(private val testOperator: TestOperator) {
fun getRandomValueFromCTest(): Int = testOperator.generateRandomNumber()
}
class TestOperator @Inject constructor() {
fun generateRandomNumber(): Int = Random.nextInt()
}
TestClass.kt & TestOperator.kt dans le même fichier:
@Singleton
@Component(modules = [
AndroidInjectionModule::class,
AppModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: App): Builder
fun build(): AppComponent
}
}
App.kt :
@Module
class AppModule {
@Provides
@Singleton
fun provideApplication(app: App): Application = app
@Provides
@Singleton
fun provideTestOperator(testOperator: TestOperator) = testOperator
@Provides
@Singleton
fun provideTestClass(testClass: TestClass) = testClass
}
3 Réponses :
MainActivity doit étendre DaggerActivity , pas AppCompatActivity
Ce n'est pas vrai, en fait. Il peut étendre DaggerActivity mais ce n'est pas obligatoire. Il suffit d'appeler AndroidInjection.inject (/ * ... * /) dans la méthode onCreate (/ * ... * /) .
AppModule.kt : indiquez le contexte de l'application. Pas besoin d'écrire @singleton @provides pour vos classes Test * (vous verrez pourquoi)
class MainActivity : DaggerAppCompatActivity() {
@Inject
lateinit var testClass: TestClass
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onResume() {
super.onResume()
val x = testClass.getRandomValueFromCTest()
}
}
AppComponent.kt : @ Component.Builder code > est obsolète IIRC. Utilisez @ Component.Factory . Et remplacez AndroidInjectionModule :: class par AndroidSupportInjectionModule :: class puisque nous utilisons dagger-android-support et android * Compat * trucs. Référez-vous ici à un nouveau module appelé ActivityModule::class.
@Module
interface ActivityModule {
@ContributesAndroidInjector
fun provideMainActivity(): MainActivity
}
TestClass.kt & TestOperator.kt : Depuis vous fournissaient des singletons en écrivant la méthode @singleton et @provides, je suppose que vous voulez qu'ils soient des singletons. Annotez simplement la définition de classe avec @Singleton et la dague s'en occupera. Pas besoin d'écrire des méthodes @Provides.
class App : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.factory().create(this)
}
}
App.kt : Utilisation de l'usine au lieu du générateur depuis @ Component.Builder code > est obsolète.
@Singleton
class TestClass @Inject constructor(private val testOperator: TestOperator) {
fun getRandomValueFromCTest(): Int = testOperator.generateRandomNumber()
}
@Singleton
class TestOperator @Inject constructor() {
fun generateRandomNumber(): Int = Random.nextInt()
}
ActivityModule.kt : Fournissez un module à dagger pour créer vos activités.
@Singleton
@Component(modules = [
ActivityModule::class
AndroidSupportInjectionModule::class,
AppModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Factory
abstract class Factory : AndroidInjector.Factory<App>
}
MainActivity.kt : Enfin, étendez à partir de DaggerAppCompatActivity .
@Module
class AppModule {
@Provides
@Singleton
fun provideApplication(app: App): Context = app.applicationContext
}
Je pense que cela devrait fonctionner sans problème. Pour plus d'informations, vous pouvez consulter ce sample et les nouveaux documents plus simples sur dagger.dev/android a>
Vous n'avez pas reçu l'appel d'injection.
class MainActivity : AppCompatActivity() {
@Inject
lateinit var testClass: TestClass
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}