Implementing a simple Dagger2 sample

后端 未结 3 1722
伪装坚强ぢ
伪装坚强ぢ 2020-12-02 02:37

I\'m new using Dagger2 (I always used Koin) and I\'m trying to implement a simple sample but I don\'t really know what I\'m missing. This is what I got so far.

a

相关标签:
3条回答
  • 2020-12-02 03:13

    AppModule.kt: Provide the application context. No need to write @singleton @provides for your Test* classes (will see why)

    @Module
    class AppModule {
        @Provides
        @Singleton
        fun provideApplication(app: App): Context = app.applicationContext
    }
    

    AppComponent.kt: @Component.Builder is deprecated IIRC. Use @Component.Factory. And replace AndroidInjectionModule::class with AndroidSupportInjectionModule::class since we are using dagger-android-support and android's *Compat* stuff. Refer a new module here called ActivityModule::class.

    @Singleton
    @Component(modules = [
        ActivityModule::class
        AndroidSupportInjectionModule::class,
        AppModule::class
    ])
    interface AppComponent : AndroidInjector<App> {
    
        @Component.Factory
        abstract class Factory : AndroidInjector.Factory<App>
    }
    

    TestClass.kt & TestOperator.kt: Since you were providing singletons by writing @singleton and @provides method, I assume you want them to be singletons. Just annotate the class definition with @Singleton and dagger will take care of it. No need to write @Provides methods.

    @Singleton
    class TestClass @Inject constructor(private val testOperator: TestOperator) {
        fun getRandomValueFromCTest(): Int = testOperator.generateRandomNumber()
    }
    
    @Singleton
    class TestOperator @Inject constructor() {
        fun generateRandomNumber(): Int = Random.nextInt()
    }
    

    App.kt: Using factory instead of builder since @Component.Builder is deprecated.

    class App : DaggerApplication() {
        override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
            return DaggerAppComponent.factory().create(this)
        }
    }
    

    ActivityModule.kt: Provide a module to dagger to create your activities.

    @Module
    interface ActivityModule {
    
        @ContributesAndroidInjector
        fun provideMainActivity(): MainActivity
    }
    

    MainActivity.kt: Finally, extend from DaggerAppCompatActivity.

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

    I believe this should run without issues. For more reference you could look into this sample and the new simpler docs at dagger.dev/android

    0 讨论(0)
  • 2020-12-02 03:25

    MainActivity should extends DaggerActivity, not AppCompatActivity

    0 讨论(0)
  • 2020-12-02 03:34

    You are missing the actual injection call.

    class MainActivity : AppCompatActivity() {
      @Inject
      lateinit var testClass: TestClass
    
      override fun onCreate(savedInstanceState: Bundle?) {
          AndroidInjection.inject(this)
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
      }
    
    0 讨论(0)
提交回复
热议问题