You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Kotlin的UninitializedPropertyAccessException未初始化属性访问异常?

问题分析与解决方案

针对你遇到的PractiseAdapter中lateinit变量imageResources已赋值但仍抛出kotlin.UninitializedPropertyAccessException的问题,结合RecyclerView适配器与单例类的常见坑点,给出以下排查方向和解决方法:

核心原因排查与解决

1. 适配器实例重复创建,部分实例未完成赋值

RecyclerView的适配器可能被多次初始化,但只有部分实例执行了imageResources的赋值操作。当未赋值的适配器实例触发onBindViewHolder时,就会抛出异常。

  • 解决方法:将imageResources作为构造参数传入适配器,从根源避免延迟初始化的时序问题:
    class PractiseAdapter(private val imageResources: List<Int>) : RecyclerView.Adapter<PractiseViewHolder>() {
        // 直接使用构造参数,无需lateinit声明
        override fun onBindViewHolder(holder: PractiseViewHolder, position: Int) {
            holder.imageView.setImageResource(imageResources[position])
        }
    }
    

2. 单例ImageStore初始化滞后于适配器

如果ImageStore是懒加载单例,可能在适配器尝试获取资源时还未完成初始化,导致imageResources实际未被正确赋值。

  • 解决方法:改用by lazy延迟获取资源,确保在首次使用时单例已初始化:
    class PractiseAdapter : RecyclerView.Adapter<PractiseViewHolder>() {
        private val imageResources by lazy { ImageStore.getInstance().getImageResources() }
        
        override fun onBindViewHolder(holder: PractiseViewHolder, position: Int) {
            holder.imageView.setImageResource(imageResources[position])
        }
    }
    

3. 赋值时机晚于onBindViewHolder调用

若imageResources的赋值操作在子线程执行,或在适配器绑定数据之后才完成,会导致访问时变量仍未初始化。

  • 解决方法:添加初始化状态检查,避免直接访问未初始化的变量:
    class PractiseAdapter : RecyclerView.Adapter<PractiseViewHolder>() {
        private lateinit var imageResources: List<Int>
        
        fun setImageResources(resources: List<Int>) {
            this.imageResources = resources
            notifyDataSetChanged() // 赋值后立即通知刷新,确保后续绑定数据时变量已初始化
        }
        
        override fun onBindViewHolder(holder: PractiseViewHolder, position: Int) {
            if (::imageResources.isInitialized) {
                holder.imageView.setImageResource(imageResources[position])
            } else {
                holder.imageView.setImageResource(R.drawable.default_image) // 兜底默认资源
            }
        }
    }
    

4. 变量被意外重置或实例复用异常

某些场景下,适配器实例被复用但imageResources未重新赋值,导致之前的初始化状态失效。

  • 解决方法:改用可空变量配合空安全调用,虽然不如lateinit简洁,但能避免初始化异常:
    class PractiseAdapter : RecyclerView.Adapter<PractiseViewHolder>() {
        private var imageResources: List<Int>? = null
        
        override fun onBindViewHolder(holder: PractiseViewHolder, position: Int) {
            imageResources?.let { resources ->
                holder.imageView.setImageResource(resources[position])
            } ?: run {
                holder.imageView.setImageResource(R.drawable.default_image)
            }
        }
    }
    

额外排查提示

结合Logcat报错指向onBindViewHolder的调用栈,重点确认:

  • 每次创建PractiseAdapter实例时,是否都同步执行了imageResources的赋值操作
  • ImageStore.getInstance().getImageResources()是否返回了非空的有效资源列表
  • 适配器是否在未完成赋值的情况下就被设置给了RecyclerView

内容的提问来源于stack exchange,提问作者kolmikaelson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:10:15