I'm trying to inject the ViewModelFactory into my Activity, but it keeps throwing this same error: lateinit property viewModelFactory has not been initialized. I can't find what I may be doing wrong. See the code above from my classes
AppComponent.kt
@Component(modules = [(AppModule::class), (NetworkModule::class), (MainModule::class)]) interface AppComponent { fun inject(application: TweetSentimentsApplication) fun inject(mainActivity: MainActivity) fun context(): Context fun retrofit(): Retrofit }
MainModule.kt
@Module class MainModule { @Provides fun mainViewModelFactorty(repository: TweetRepository): MainViewModelFactory = MainViewModelFactory(repository) @Provides fun local(database: AppDatabase): TweetLocal = TweetLocal(database) @Provides fun remote(tweetService: TweetService): TweetRemote = TweetRemote(tweetService) @Provides fun tweetService(retrofit: Retrofit): TweetService = retrofit.create(TweetService::class.java) @Provides fun repository(local: TweetLocal, remote: TweetRemote): TweetRepository = TweetRepository(local, remote) }
MainActivity.kt
class MainActivity : AppCompatActivity() { @Inject lateinit var viewModelFactory: MainViewModelFactory private val viewModel: MainViewModel? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java) viewModel?.init("guuilp") viewModel?.getTweetList()?.observe(this, Observer { Toast.makeText(this, it?.size.toString(), Toast.LENGTH_LONG).show() }) } }
TweetSentimentsApplication.kt
open class TweetSentimentsApplication: Application(){ companion object { lateinit var appComponent: AppComponent } override fun onCreate() { super.onCreate() initDI() } private fun initDI() { appComponent = DaggerAppComponent.builder() .appModule(AppModule(this)) .build() } }
Kotlin lateinit – To declare non null Kotlin Variables without initialization, use lateinit keyword during declaration of the variable. Initialization of that variable could be done at a later point in code. Note : lateinit is supported from Kotlin 1.2. Make sure you are updated to latest Kotlin.
If you try accessing Lateinit variables without initializing, it will throw an exception stating that it is not initialized or properly being accessed.
In order to avoid this situation, Kotlin introduced a new modifier called as "lateInit". Along with this modifier, Kotlin provides a couple of methods to check whether this variable is initialized or not. Use "lateInit" with a mutable variable. That means, we need use "var" keyword with "lateInit".
The lateinit keyword allows you to avoid initializing a property when an object is constructed. If your property is referenced before being initialized, Kotlin throws an UninitializedPropertyAccessException , so be sure to initialize your property as soon as possible.
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) ... }
Also, make sure that your application name is added in the AndroidManifest.xml file.
<application android:name=".YourAppName" ..../>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With