UninitializedPropertyAccessException: lateinit property pref has not been initialized

61,512

You can't use an object before you initialize it.

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState) // prefs called in parents onCreate!
  setContentView(R.layout.activity_login)
  AndroidInjection.inject(this) // injection happens here

Get your calls in order. Easiest way to fix would be to move AndroidInjection.inject(this) before the call to super.onCreate(...).

Share:
61,512
Tarun
Author by

Tarun

Updated on April 25, 2021

Comments

  • Tarun
    Tarun about 3 years

    I know a similar question has been answered Here. But that was due to butter knife library problem but my case is different. In my case when I use dagger injected properties in my base activity it shows me error Caused by: kotlin.UninitializedPropertyAccessException: lateinit property pref has not been initialized

    But the same property when I use in my sub activity (Login activity) it works fine.

    eg. pref.setLanguage("abc") -> it works fine in login activity but throws error in base activity

    Here is my code:

    BaseActivity

        abstract class BaseActivity : AppCompatActivity() {
        @Inject
        lateinit var pref: AppSharedPreferences
        @Inject
        lateinit var utils: Utils
        lateinit var mCurrentLanguage: String
        protected lateinit var progressBarUtils: ProgressBarUtils
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            progressBarUtils = ProgressBarUtils(this)
            mCurrentLanguage = "EN"
            pref.setSelectedLanguage(mCurrentLanguage)   
        }
        }
    

    LoginActivity

        class LoginActivity : BaseActivity() {
        private val TAG = this.javaClass.name
        lateinit var loginViewModel: LoginViewModel
        @Inject
        lateinit var viewModelFactory: LoginViewModelFactory
    
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_login)
            AndroidInjection.inject(this)
            loginViewModel = ViewModelProviders.of(this, viewModelFactory).get(
                    LoginViewModel::class.java)
            loadData("abc", "xyz")
            observerOnLoginResult()
            observerOnLoginError()
        }
    
    
        private fun observerOnLoginError() {
            loginViewModel.loginError().observe(this, Observer<String> {
                progressBarUtils.cancelProgressDialog()
                if (it != null) {
                    Toast.makeText(this, resources.getString(R.string.error_message) + it,
                            Toast.LENGTH_SHORT).show()
                }
            })
        }
    
        private fun observerOnLoginResult() {
            loginViewModel.loginResult().observe(this,
                    Observer<LoginModel> {
                        progressBarUtils.cancelProgressDialog()
                        if (it != null) {
                            setData(it)
                        }
                    })
        }
    
        private fun setData(loginData: LoginModel) {
            pref.setCurrentUserName(loginData.data.userName)
        }
    
        private fun loadData(email: String, password: String) {
            progressBarUtils.showProgressDialog()
            val builder = StringBuilder()
            var auth = Base64.encodeToString(("$email:$password").toByteArray(), Base64.NO_WRAP)
            builder.append("Basic ")
            builder.append(auth)
            loginViewModel.getLoginData(builder.toString())
        }
    
        override fun onDestroy() {
            loginViewModel.disposeElements()
            super.onDestroy()
        }
    

    AppModule

        @Module class AppModule(val app: Application) {
    
        @Provides
        @Singleton
        fun provideApplication(): Application = app
    
    
        @Provides
        @Singleton
        fun provideSharedPreferences(): AppSharedPreferences = AppSharedPreferences(app)
    
    
        @Provides
        @Singleton
        fun provideUtils(): Utils = Utils(app)
        }
    

    Builder Module

        @Module abstract class BuildersModule {
    
        @PerActivity
        @ContributesAndroidInjector(modules = arrayOf(LoginModule::class))
        abstract fun contributeLoginActivity(): LoginActivity
    
        @PerActivity
        abstract fun contributeBaseActivityActivity(): BaseActivity
        }
    

    AppComponent

        @Singleton @Component(
            modules = arrayOf(AndroidInjectionModule::class, AppModule::class, BuildersModule::class))
    
        interface AppComponent { 
          fun inject(app: LotusApp)            
        }