1
votes

I have this issue when I try to use Kotlin and Dagger 2 .

"interface cannot be provided without an @Provides- or @Produces-annotated method.”

This is my Module class:

@Module
class MenuActivityModule(@NonNull private val menuActivity: MenuActivity) {

    @Provides
    @MenuActivityScope
    fun provideGameScreenDimensions(application: Application) =
            GameScreenDimension(application.resources)

    @Provides
    @MenuActivityScope
    fun provideAudio() =
            AndroidAudio(menuActivity)

    @Provides
    @MenuActivityScope
    fun providePowerManager() =
            menuActivity.getSystemService(Context.POWER_SERVICE) as PowerManager

    @Provides
    @MenuActivityScope
    fun provideWakeLock(@NonNull powerManager: PowerManager) =
        powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Preferences.APPLICATION_TAG)
}

This is a part of my Activity class, where I inject some variables with Dagger:

class MenuActivity : BaseActivity {

    @Inject
    lateinit var myAudio: Audio
    @Inject
    lateinit var wakeLock: PowerManager.WakeLock
    @Inject
    lateinit var apiService : ApiService
    @Inject
    lateinit var sharedPref : SharedPreferences
    @Inject
    lateinit var gameDimension : GameScreenDimension

    init {
        DaggerMenuActivityComponent.builder()
                .menuActivityModule(MenuActivityModule(this))
                .build()
                .inject(this)
    }
    //more code
}

Audio.kt is interface and Dagger has problem to inject it. Inside the activity module I am returning AndroidAudio instance, which implements Audio interface. I am not sure what is the problem here. In Java I have had many times injection of interfaces and I never had this issue before. If somebody can help me I will be so happy. Thanks!

1

1 Answers

4
votes

I think the solution for your problem is very simple and also not so obvious unfortunately.

Because Kotlin does not require type to be specified on methods return, you can easily write something like this:

@Provides
@MenuActivityScope
fun provideAudio() =
        AndroidAudio(menuActivity)

And the compiler will not complain about that, but in this case Dagger will provide AndroidAudio object for injection. In you Activity you are looking for Audio object for injection. So if you change this code to be:

@Provides
@MenuActivityScope
fun provideAudio(): Audio =
        AndroidAudio(menuActivity)

Everything should be ОК. Give a try and tell me if something does not work. Thanks.

BTW : When I use Dagger with Kotlin I aways specify the type of returned value, because usually that is gonna be the type of the injected variables or the type of the variable which you are going to use in your dagger module.