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) }