Как создать модуль, состоящий из @ContributesAndroidInjector в кинжал с kotlin? - PullRequest
2 голосов
/ 22 января 2020

Я изучаю кинжал 2, сейчас я использую dagger-2.25.4 на kotlin, я создал класс BaseApplication для кинжала, приведенный ниже:

package com.example.demomvvm

import com.example.demomvvm.dagger.DaggerAppComponent
import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication

class MVVMApplication: DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication>? {
        return DaggerAppComponent.builder().application(this).build()
    }
}

А вот мой класс AppComponent:

package com.example.demomvvm.dagger

import android.app.Application
import com.example.demomvvm.MVVMApplication
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjector
import dagger.android.support.AndroidSupportInjectionModule

@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        ActivityBuilderModule::class
    ]
)
interface AppComponent: AndroidInjector<MVVMApplication> {

    @Component.Builder
    interface Builder{

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}

Мой ActivityBuilderModule не генерируется правильно, вот мой ActivityBuilderModule.kt:

package com.example.demomvvm.dagger

import com.example.demomvvm.ui.auth.LoginActivity
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector

@Module
abstract class ActivityBuilderModule {

    @ContributesAndroidInjector
    abstract fun contributeLoginActivity(): LoginActivity

    @Provides
    fun doSomething(): String = "This is a string"
}

Это ошибка, которую я получаю в сгенерированном Dagger коде:

/home/suvodip/AndroidStudioProjects/demoMVVM/app/build/tmp/kapt3/stubs/debug/com/example/demomvvm/dagger/AppComponent.java:7: error: [Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.demomvvm.MVVMApplication> {
                ^
      java.lang.String is injected at
          com.example.demomvvm.ui.auth.LoginActivity.dagger
      com.example.demomvvm.ui.auth.LoginActivity is injected at
          dagger.android.AndroidInjector.inject(T) [com.example.demomvvm.dagger.AppComponent → com.example.demomvvm.dagger.ActivityBuilderModule_ContributeLoginActivity.LoginActivitySubcomponent]

Я делаю это здесь:

package com.example.demomvvm.ui.auth

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import dagger.android.support.DaggerAppCompatActivity
import kotlinx.android.synthetic.main.activity_login.*
import javax.inject.Inject

class LoginActivity : DaggerAppCompatActivity(), AuthListener {

    @Inject
    lateinit var dagger: String

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Dagger", "$dagger")

    }
}

1 Ответ

0 голосов
/ 23 января 2020

@ SuvodipMondal Добро пожаловать в сообщество.

Ошибка, которую вы получаете, заключается в том, что методы @Binds и @ContributesAndroidInjector должны быть абстрактными, поскольку они не имеют тел методов. Это означает, что они должны go на интерфейсе или абстрактном классе. Методы @Provides могут быть stati c, что означает, что они могут go на абстрактных классах и Java -8-скомпилированных интерфейсах, но нестатические c ("instance") @Provides методы не работа на абстрактных классах. Это явно указано в Dagger FAQ «Почему нельзя @Binds и экземпляр @Provides методов go в одном и том же модуле?»

Для достижения этого вам необходимо иметь stati c функция в вашем абстрактном классе Аннотированный с @JvmStatic

Вы должны добавить это.

@Module
companion object{
  @JvmStatic
  @Provides
  fun doSomething(): String = "This is a string"
}

Тогда ваш класс станет таким.

package com.example.demomvvm.dagger

import com.example.demomvvm.ui.auth.LoginActivity
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector

@Module
abstract class ActivityBuilderModule {

    @ContributesAndroidInjector
    abstract fun contributeLoginActivity(): LoginActivity

    @Module
    companion object{
     @JvmStatic
     @Provides
     fun doSomething(): String = "This is a string"
   }
}

Для получения дополнительной информации 1 & 2

...