Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2 + Kotlin: lateinit property has not been initialized

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()     } } 
like image 311
Guilherme Lima Pereira Avatar asked May 27 '18 17:05

Guilherme Lima Pereira


People also ask

How do you initialize Lateinit in Kotlin?

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.

What if Lateinit is not initialized?

If you try accessing Lateinit variables without initializing, it will throw an exception stating that it is not initialized or properly being accessed.

How do I know if Lateinit is initialized?

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".

What is Lateinit in Kotlin example?

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.


2 Answers

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)      ... } 
like image 131
zsmb13 Avatar answered Sep 18 '22 11:09

zsmb13


Also, make sure that your application name is added in the AndroidManifest.xml file.

<application     android:name=".YourAppName"     ..../> 
like image 26
Ritesh R Avatar answered Sep 20 '22 11:09

Ritesh R