简体   繁体   中英

Dagger 2 + Kotlin can't inject Presenter into View

I am trying to create simple MVP Archtecture app using Dagger 2. I am tying to achieave same result as in this tutorial, but with Kotlin. Here is my code so far.

Presenter:

class MainPresenter @Inject constructor(var view: IMainView): IMainPresenter{

override fun beginMessuring() {
    view.toastMessage("Measuring started")
}

override fun stopMessuring() {
    view.toastMessage("Measuring stopped")
}

}

View:

class MainActivity : AppCompatActivity(), IMainView {

@Inject lateinit var presenter : MainPresenter

val component: IMainComponent by lazy {
    DaggerIMainComponent
            .builder()
            .mainPresenterModule(MainPresenterModule(this))
            .build()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    component.inject(this)
    presenter.beginMessuring()
}

override fun toastMessage(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_LONG).show()
}
}

Dagger Module:

@Module
class MainPresenterModule(private val view: IMainView) {
    @Provides
    fun provideView() = view
}

Dagger Component:

@Component(modules = arrayOf(MainPresenterModule::class))
interface IMainComponent {
    fun inject(mainView : IMainActivity)
}

The problem is that I am getting build error which starts with this:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.maciej.spiritlvl/com.example.maciej.spiritlvl.View.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property presenter has not been initialized

PS, my gradle dagger config:

kapt 'com.google.dagger:dagger-compiler:2.9'
mplementation 'com.google.dagger:dagger:2.9'

EDIT: Changed injected presenter type from IMainView to MainView.

Whenever trying to inject any interface, like in your case IMainPresenter , you need to tell dagger which concrete implementation to use. Dagger has no means of knowing which implementation of that interface you want to 'have' (you might have numerous implementations of that interface).

You did the right thing for the IMainView by adding a @Provides -annotated method to your module. You can do the same for your presenter, but that imho would render the whole point of dagger useless, because you'd have to create the presenter yourself when creating the module.

So I would, instead of injecting the IMainPresenter interface into your activity, inject the concrete implementation MainPresenter . Then you also shouldn't need a @Provides method in your module (for the presenter).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM