MVP presenter incorrectly entered

I am learning Kotlin and Dagger 2 at the same time, trying to convert some of the Mindorks advanced MVP sample to Kotlin, but I have problems compiling Dagger2. I am swimming in the classes here, but very close! Ignore the sloppiness, I'm going to comb every class after compiling it. If something is missing, please let me know. The error boils down to the fact that my presenter class was not properly enforced. The error is read as follows:

e: D:\_Dev\repo\app\build\tmp\kapt3\stubs\debug\com\xxx\di\component\ActivityComponent.java:8: error: com.xxx.login.LoginMVP.Presenter<com.xxx.login.LoginMVP.View,? extends com.xxx.login.LoginMVP.Interactor> cannot be provided without an @Provides- or @Produces-annotated method.
e: 

e:     public abstract void inject(@org.jetbrains.annotations.NotNull()
e:                          ^
e:       com.xxx.login.LoginMVP.Presenter<com.xxx.login.LoginMVP.View,? extends com.xxx.login.LoginMVP.Interactor> is injected at
e:           com.xxx.login.LoginActivity.presenter
e:       com.xxx.login.LoginActivity is injected at
e:           com.xxx.di.component.ActivityComponent.inject(activity)
e: java.lang.IllegalStateException: failed to analyze: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing

EDIT:

Here is a repo with unsuccessful code built using the latest canary build of Android Studio

BaseActivity.kt

abstract class BaseActivity : AppCompatActivity(), MvpView {

    val activityComponent: ActivityComponent by lazy {
        DaggerActivityComponent.builder()
                .applicationComponent((application as App).applicationComponent)
                .activityModule(ActivityModule(this))
                .build()
    }
}

BasePresenter.kt

open class BasePresenter<V : MvpView, out I: MvpInteractor>
@Inject constructor(private val mvpInteractor: I) : MvpPresenter<V, I> {

    private var mvpView: V? = null

    override fun onAttach(mvpView: V) {
        this.mvpView = mvpView
    }

    override fun onDetach() {
        mvpView = null
    }

    override fun getMvpView(): V? {
        return mvpView
    }

    override fun getInteractor(): I {
        return mvpInteractor
    }

}

MvpPresenter.kt (MvpView and MvpInteractor - basic empty interfaces)

interface MvpPresenter<V: MvpView, out I: MvpInteractor> {

    fun onAttach(mvpView: V)

    fun onDetach()

    fun getMvpView(): V?

    fun getInteractor(): I
}

App.kt

class App: Application() {

    lateinit var applicationComponent: ApplicationComponent

    override fun onCreate() {
        super.onCreate()
        applicationComponent = DaggerApplicationComponent.builder()
                .applicationModule(ApplicationModule(this)).build()

        applicationComponent.inject(this)
    }

    fun getComponent(): ApplicationComponent {
        return applicationComponent
    }

    fun setComponent(applicationComponent: ApplicationComponent) {
        this.applicationComponent = applicationComponent
    }
}

ApplicationComponent.kt

@Singleton
@Component(modules = arrayOf(ApplicationModule::class))
interface ApplicationComponent {

    fun inject(app: App)

    @ApplicationContext fun context(): Context

    fun application(): Application

    //Pref helper
    //Api helper
}

ApplicationModule.kt

@Module
class ApplicationModule(val application: Application) {

    @Provides
    @ApplicationContext
    fun provideContext(): Context = application

    @Provides
    fun provideApplication(): Application = application

    //Provide api helper

    //Provide pref helper

    //Provide api key etc.
}

ActivityModule.kt

@Module
class ActivityModule(val activity: AppCompatActivity) {

    @Provides
    fun provideContext(): Context = activity

    @Provides
    fun provideActivity(): AppCompatActivity = activity

    @Provides
    fun provideLoginPresenter(presenter: LoginPresenter<LoginMVP.View, LoginMVP.Interactor>):
            LoginMVP.Presenter<LoginMVP.View, LoginMVP.Interactor> {
        return presenter
    }

    @Provides
    fun provideLoginMvpInteractor(interactor: LoginInteractor):
            LoginMVP.Interactor {
        return interactor
    }

}

ActivityComponent.kt

@PerActivity
@Component(dependencies = arrayOf(ApplicationComponent::class), modules = arrayOf(ActivityModule::class))
interface ActivityComponent {

    fun inject(activity: LoginActivity)
}

LoginActivity.kt

class LoginActivity : BaseActivity(), LoaderCallbacks<Cursor>, LoginMVP.View {

    @Inject lateinit var presenter: LoginMVP.Presenter<LoginMVP.View, LoginMVP.Interactor>

    private var authTask: UserLoginTask? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        activityComponent.inject(this)

        email_sign_in_button.setOnClickListener { presenter.onServerLoginClick(email.text.toString(), password.text.toString()) }

        presenter.onAttach(this)
    }
}

LoginMVP.kt

interface LoginMVP {

    interface Interactor : MvpInteractor {

    }

    @PerActivity
    interface Presenter<V : LoginMVP.View, out I : LoginMVP.Interactor>
        : MvpPresenter<V, I> {

        fun onServerLoginClick(email: String, password: String)

    }

    interface View : MvpView {
        fun openMainActivity()
    }
}
+4
1

, .

out. Dagger

com.xxx.login.LoginMVP.Presenter<com.xxx.login.LoginMVP.View,? extends com.xxx.login.LoginMVP.Interactor>

  com.xxx.login.LoginMVP.Presenter<com.xxx.login.LoginMVP.View, com.xxx.login.LoginMVP.Interactor>  

( provideLoginPresenter).

, out ( Presenter, BasePresenter, LoginPresenter), .

, Dagger , . . , - out .

+3

Source: https://habr.com/ru/post/1682534/


All Articles