Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger + Kotlin not injecting

I studying Dagger 2 for DI and I just did this code to inject the Retrofit:

NetModule.kt

@Module
class NetModule(val baseUrl: String) {

    @Provides
    @Singleton
    fun provideRetrofit() : Retrofit{
        [some logic here]
    }
}

AppModule.kt

@Module
class AppModule(val mApplication: Application) {

    @Provides
    @Singleton
    fun provideApplication() : Application{
        return mApplication
    }
}

NetComponent.kt:

@Singleton
@Component(modules = arrayOf(AppModule::class, NetModule::class))
interface NetComponent {
    fun inject(activity: Activity)
}

CustomApplication.kt

class CustomApplication : Application() {

    companion object {
        lateinit var mNetComponent: NetComponent
    }

    override fun onCreate() {
        super.onCreate()

        AndroidThreeTen.init(this)

        mNetComponent = DaggerNetComponent.builder()
                            .appModule(AppModule(this))
                            .netModule(NetModule(getString(R.string.api_base_url)))
                            .build()

    }
}

Then in my activity:

class TrashCansInfoActivity : AppCompatActivity(){

@Inject
    lateinit var mRetrofit: Retrofit

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

        CustomApplication.mNetComponent.inject(this)

        setSupportActionBar(toolbar)

        populateTrashCanList()

    }

    private fun populateTrashCanList(){
        showProgress(true)
        mRetrofit.create(ApiClient::class.java)
                .getTrashCans()
                .map { it.map { it.toTrashCan() } }
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnError {
                    showProgress(false)
                    Toast.makeText(this, "Erro ao carregar lista de lixeiras", Toast.LENGTH_SHORT).show()
                }.doOnCompleted { showProgress(false) }
                .subscribe(behaviorSubject)
    }

}

So, this code should work, right? The dependency should be added... But when I run my app... I get this:

kotlin.UninitializedPropertyAccessException: lateinit property mRetrofit has not been initialized

So the Retrofit is not being injected. What am I missing?

Any help is welcome!

like image 737
Leandro Borges Ferreira Avatar asked Nov 22 '16 12:11

Leandro Borges Ferreira


People also ask

Does dagger work with Kotlin?

Dagger is a fully static, compile-time dependency injection framework for Java, Kotlin, and Android.

What does @inject do in Kotlin?

@Inject is a Java annotation for describing the dependencies of a class that is part of Java EE (now called Jakarta EE). It is part of CDI (Contexts and Dependency Injection) which is a standard dependency injection framework included in Java EE 6 and higher.

How do you inject a constructor in Kotlin?

We use @Inject annotation at the top of the constructor. Field Injection: In this technique , the dependencies are injected as part of fields in the classes that require them. @Inject annotation is used for the fields to be injected.


2 Answers

I got the same error. The mistake was - not injecting the component. Also i had to inject the component in a fragment. (in kotlin)

val component = (activity?.application as MyApplication).appComponent component.plus(FakeModule(this)).inject(this)

This solved the error.

like image 137
anoo_radha Avatar answered Oct 18 '22 01:10

anoo_radha


fun inject(activity: Activity)

should be

fun inject(activity: TrashCansInfoActivity)
like image 23
EpicPandaForce Avatar answered Oct 18 '22 00:10

EpicPandaForce