android - UninitializedPropertyAccessException:lateinit 属性首选项尚未初始化
问题描述
我知道已经回答了一个类似的问题Here。但那是由于黄油刀库问题,但我的情况不同。在我的情况下,当我在我的基本活动中使用匕首注入属性时,它显示错误原因:kotlin.UninitializedPropertyAccessException:lateinit 属性首选项尚未初始化
但是当我在我的子活动(登录活动)中使用相同的属性时,它可以正常工作。
例如。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()
}
应用模块
@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)
}
解决方案
在初始化对象之前,您不能使用它。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) // prefs called in parents onCreate!
setContentView(R.layout.activity_login)
AndroidInjection.inject(this) // injection happens here
按顺序接听电话。最简单的修复方法是AndroidInjection.inject(this)
在调用super.onCreate(...)
.
推荐阅读
- mysql - MySQL 错误代码 1055 与 group by/average
- api - Shopify 购物车 - FrontStore API(购物车 ID)X ajax API(令牌)
- javascript - 使用catch on 然后会产生额外的承诺吗?
- android - 如何使用范围存储创建和删除公共文件,Android Q
- javascript - 在 React Router v6.+ 中渲染多个元素
- java - 我有一个关于求和问题的 Java 逻辑问题
- reactjs - React 多条件检查(JSX)
- javascript - 如何根据单击的按钮动态更改从 API 获取的数据?
- php - 将外部 /api/entity/1 URL 重写为内部 /api/entity.php/1(或 /api/entity.php?id=1)的通用方法
- nouislider - noUISlider - 在连接段内放置标签的任何方式