Dagger2 + Kotlin: lateinit property has not been initialized
You can also do this:
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
val mainViewModel: MainViewModel by lazy {
ViewModelProviders.of(this, viewModelFactory)[MainViewModel::class.java]
}
and use abstract modules with @ContributesAndroidInjector for the activity, and abstract module for view model. Using abstract is more efficient:
@Module
abstract class AndroidBindingModule {
@ContributesAndroidInjector
internal abstract fun contributesAnActivity(): AnActivity
}
@Module
abstract class ViewModelModule {
//the default factory only works with default constructor
@Binds
@IntoMap
@ViewModelKey(AViewModel::class)
abstract fun bindArtViewModel(aViewModel: AViewModel): ViewModel
@Binds
abstract fun bindViewModelFactory(factory: AViewModelFactory): ViewModelProvider.Factory
}
@Documented
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
Also, make sure that your application name is added in the AndroidManifest.xml file.
<application
android:name=".YourAppName"
..../>
You have to call the inject(mainActivity: MainActivity)
method you've defined in AppComponent
when you're initializing your MainActivity
, that's how Dagger actually injects the dependencies you need.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
// This is where the dependencies are injected
TweetSentimentsApplication.appComponent.inject(this)
ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
...
}