Android ViewModel报UninitializedPropertyAccessException异常
问题说明
Kotlin与Android Studio开发新手,在结合Room数据库与ViewModel实现功能时,遇到报错:
kotlin.UninitializedPropertyAccessException: lateinit property habitViewModel has not been initialized
初步判断是ViewModel初始化顺序问题,但未找到有效修复方案,相关代码与配置如下:
Activity onCreate 代码
class HabitActivity : AppCompatActivity() { lateinit var binding : ActivityHabitBinding lateinit var habitViewModel : HabitViewModel lateinit var habitAdapter: HabitAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHabitBinding.inflate(layoutInflater) habitViewModel = ViewModelProvider(this)[habitViewModel::class.java] setContentView(binding.root) // view model habitViewModel.habitList.observe(this) { habitAdapter.update(it) } // adapter habitAdapter = HabitAdapter(this) binding.rvHabitList.layoutManager = LinearLayoutManager(this) binding.rvHabitList.adapter = habitAdapter }
ViewModel 代码
class HabitViewModel: ViewModel() { val habitList: LiveData<MutableList<HabitDTO>> private var habitRepository: HabitRepo = HabitRepo.get() init { habitList = habitRepository.list() } }
Build.gradle 依赖配置
def arch_version = "2.1.0" def lifecycle_version = "2.5.0-rc02" def roomVersion = "2.4.2" // Room implementation("androidx.room:room-runtime:$roomVersion") kapt("androidx.room:room-compiler:$roomVersion") implementation("androidx.room:room-ktx:$roomVersion") implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' kapt 'org.xerial:sqlite-jdbc:3.34.0' implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
修复方案
报错由两个核心问题导致,按以下修改即可解决:
- ViewModel初始化写法错误
原有初始化代码habitViewModel = ViewModelProvider(this)[habitViewModel::class.java]执行时,habitViewModel本身还是未赋值的lateinit变量,直接访问它的类引用会直接触发未初始化异常。需要把括号里的变量引用改为ViewModel类本身的引用:// 替换原有错误的ViewModel初始化代码 habitViewModel = ViewModelProvider(this)[HabitViewModel::class.java] - 代码执行顺序错误
原有代码在habitAdapter还未初始化时,就给ViewModel的LiveData设置了观察者,观察者回调中直接调用habitAdapter.update(it),后续数据返回触发回调时会再次触发lateinit未初始化异常。需要把Adapter初始化、RecyclerView配置的代码挪到设置观察者之前,调整后的onCreate代码顺序如下:override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHabitBinding.inflate(layoutInflater) setContentView(binding.root) // 第一步:初始化ViewModel habitViewModel = ViewModelProvider(this)[HabitViewModel::class.java] // 第二步:初始化Adapter、配置RecyclerView habitAdapter = HabitAdapter(this) binding.rvHabitList.layoutManager = LinearLayoutManager(this) binding.rvHabitList.adapter = habitAdapter // 第三步:设置LiveData观察者 habitViewModel.habitList.observe(this) { habitAdapter.update(it) } } - 额外优化建议
当前使用的lifecycle版本是rc预览版,协程依赖版本过旧,建议替换为稳定版避免未知兼容问题:// 替换为正式稳定版 def lifecycle_version = "2.6.2" // 升级协程依赖版本 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
内容的提问来源于stack exchange,提问作者plzhelpme
相关产品推荐
相关产品推荐

