UninitializedPropertyAccessException: lateinit 属性 尚未初始化
UninitializedPropertyAccessException: lateinit property has not been initialized
我有一个 class,我将其注入 ViewModel + ViewModel 工厂,当在 activity 的 onCreate 方法中初始化视图模型时,它表示传递的值未初始化。
下面是我的代码
我对 Kotlin 还很陌生,所以我尝试过调试,但一直卡在这个问题上。
这里是 MainActivity 代码:
class MainActivity: AppCompatActivity(), RepoSelectedListener {
@Inject
lateinit var viewModel: MainActivityListViewModel
lateinit var lifecycleOwner: LifecycleOwner
lateinit var repoSelectedListener: RepoSelectedListener
@Inject
lateinit var repository: RepoRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this, ViewModelFactory(repository)).get(MainActivityListViewModel::class.java)
repoRecyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = RepoListAdapter(viewModel, lifecycleOwner, repoSelectedListener)
}
**My ViewModel:**
class MainActivityListViewModel @Inject constructor(val
repoRepository: RepoRepository): BaseViewModel() {
//private lateinit var repoRepository: RepoRepository
private var disposable: CompositeDisposable? = null
private val repos = MutableLiveData<List<Repo>>()
private val repoLoadError = MutableLiveData<Boolean>()
private val loading = MutableLiveData<Boolean>()
init {
disposable = CompositeDisposable()
fetchRepos()
}
fun getRepos(): LiveData<List<Repo>> {
return repos
}
}
我的 ViewModelFactory:
class ViewModelFactory @Inject constructor(private val
repoRepository: RepoRepository): ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if
(modelClass.isAssignableFrom(MainActivityListViewModel::class.java))
{
@Suppress("UNCHECKED_CAST")
return MainActivityListViewModel(this.repoRepository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
我的 Class 回购:
class RepoRepository @Inject constructor(private val githubRepos:
GithubRepos){
private lateinit var repoService: GithubRepos
fun getRepositories(): Single<List<Repo>> {
return repoService.getRepos()
}
fun getSingleRepo(owner: String, name: String): Single<Repo> {
return repoService.getSingleRepo(owner, name)
}
}
这是我收到的错误:
Unable to start activity ComponentInfo{com.carllewis14.repos/com.carllewis14.repos.ui.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property
repository has not been initialized
看看我的回答(也许有帮助)
本质上,您永远不会初始化 repository: RepoRepository
。
根据您编写的代码,您也不需要 activity 中的存储库实例,它应该只在 ViewModel
的构造函数中创建(它具有注入)
您也会遇到与 private lateinit var repoService: GithubRepos
类似的问题;如果它在你的对象的构造函数中,你不必再次声明它。
这是因为您在使用实例初始化存储库之前尝试使用存储库,而没有检查其初始化。
在该变量中使用 lateinit
时。
lateinit var repository: RepoRepository
然后,在使用对象的任何方法之前,检查它是否被初始化:
if (::repository.isInitialized) {}
GL
问题代码似乎在掩盖注入
供参考
你也可以通过惰性初始化:
To create an object that will be initialized at the first access to it, we can use the lazy method:
val lazyValue: ClassWithHeavyInitialization by lazy {
numberOfInitializations.incrementAndGet()
ClassWithHeavyInitialization()
}
如果您使用的是 Kotlin 1.2,则可以轻松检查 lateinit 变量是否已初始化。如果不是,好吧,你总是可以使用 not null 方法。
无论如何,下面是检查 lateinit var 是否已初始化的方法:
if (::fullName.isInitialized) {
print("Hi, $fullName")
}
我有一个 class,我将其注入 ViewModel + ViewModel 工厂,当在 activity 的 onCreate 方法中初始化视图模型时,它表示传递的值未初始化。
下面是我的代码
我对 Kotlin 还很陌生,所以我尝试过调试,但一直卡在这个问题上。
这里是 MainActivity 代码:
class MainActivity: AppCompatActivity(), RepoSelectedListener {
@Inject
lateinit var viewModel: MainActivityListViewModel
lateinit var lifecycleOwner: LifecycleOwner
lateinit var repoSelectedListener: RepoSelectedListener
@Inject
lateinit var repository: RepoRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this, ViewModelFactory(repository)).get(MainActivityListViewModel::class.java)
repoRecyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = RepoListAdapter(viewModel, lifecycleOwner, repoSelectedListener)
}
**My ViewModel:**
class MainActivityListViewModel @Inject constructor(val
repoRepository: RepoRepository): BaseViewModel() {
//private lateinit var repoRepository: RepoRepository
private var disposable: CompositeDisposable? = null
private val repos = MutableLiveData<List<Repo>>()
private val repoLoadError = MutableLiveData<Boolean>()
private val loading = MutableLiveData<Boolean>()
init {
disposable = CompositeDisposable()
fetchRepos()
}
fun getRepos(): LiveData<List<Repo>> {
return repos
}
}
我的 ViewModelFactory:
class ViewModelFactory @Inject constructor(private val
repoRepository: RepoRepository): ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if
(modelClass.isAssignableFrom(MainActivityListViewModel::class.java))
{
@Suppress("UNCHECKED_CAST")
return MainActivityListViewModel(this.repoRepository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
我的 Class 回购:
class RepoRepository @Inject constructor(private val githubRepos:
GithubRepos){
private lateinit var repoService: GithubRepos
fun getRepositories(): Single<List<Repo>> {
return repoService.getRepos()
}
fun getSingleRepo(owner: String, name: String): Single<Repo> {
return repoService.getSingleRepo(owner, name)
}
}
这是我收到的错误:
Unable to start activity ComponentInfo{com.carllewis14.repos/com.carllewis14.repos.ui.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property
repository has not been initialized
看看我的回答(也许有帮助)
本质上,您永远不会初始化 repository: RepoRepository
。
根据您编写的代码,您也不需要 activity 中的存储库实例,它应该只在 ViewModel
的构造函数中创建(它具有注入)
您也会遇到与 private lateinit var repoService: GithubRepos
类似的问题;如果它在你的对象的构造函数中,你不必再次声明它。
这是因为您在使用实例初始化存储库之前尝试使用存储库,而没有检查其初始化。
在该变量中使用 lateinit
lateinit var repository: RepoRepository
然后,在使用对象的任何方法之前,检查它是否被初始化:
if (::repository.isInitialized) {}
GL
问题代码似乎在掩盖注入 供参考 你也可以通过惰性初始化:
To create an object that will be initialized at the first access to it, we can use the lazy method:
val lazyValue: ClassWithHeavyInitialization by lazy {
numberOfInitializations.incrementAndGet()
ClassWithHeavyInitialization()
}
如果您使用的是 Kotlin 1.2,则可以轻松检查 lateinit 变量是否已初始化。如果不是,好吧,你总是可以使用 not null 方法。
无论如何,下面是检查 lateinit var 是否已初始化的方法:
if (::fullName.isInitialized) {
print("Hi, $fullName")
}