UninitializedPropertyAccessException:lateinit 属性首选项尚未初始化

Posted

技术标签:

【中文标题】UninitializedPropertyAccessException:lateinit 属性首选项尚未初始化【英文标题】:UninitializedPropertyAccessException: lateinit property pref has not been initialized 【发布时间】:2018-11-07 18:29:20 【问题描述】:

我知道Here 已经回答了类似的问题。但那是由于黄油刀库问题,但我的情况不同。在我的情况下,当我在基本活动中使用 dagger 注入属性时,它显示错误 Caused by: kotlin.UninitializedPropertyAccessException: lateinit property pref has not been initialized

但是当我在子活动(登录活动)中使用相同的属性时,它可以正常工作。

例如。 pref.setLanguage("abc") -> 它在登录活动中工作正常,但在基本活动中抛出错误

这是我的代码:

基础活动

    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)   
    
    

登录活动

    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)
    

生成器模块

    @Module abstract class BuildersModule 

    @PerActivity
    @ContributesAndroidInjector(modules = arrayOf(LoginModule::class))
    abstract fun contributeLoginActivity(): LoginActivity

    @PerActivity
    abstract fun contributeBaseActivityActivity(): BaseActivity
    

应用组件

    @Singleton @Component(
        modules = arrayOf(AndroidInjectionModule::class, AppModule::class, BuildersModule::class))

    interface AppComponent  
      fun inject(app: LotusApp)            
    

【问题讨论】:

【参考方案1】:

你不能在初始化之前使用一个对象。

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

按顺序接听电话。最简单的修复方法是在调用 super.onCreate(...) 之前移动 AndroidInjection.inject(this)

【讨论】:

我忘了添加 AndroidInjection.inject(this) 。谢谢@大卫。

以上是关于UninitializedPropertyAccessException:lateinit 属性首选项尚未初始化的主要内容,如果未能解决你的问题,请参考以下文章