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

生产环境NotificationAdapter空指针崩溃Firebase上报问题

生产环境NotificationAdapter空指针崩溃修复

问题现象

  • 测试构建版本运行完全正常,生产构建版本触发崩溃
  • 崩溃事件通过Firebase Crashlytics上报
  • 崩溃核心信息:NotificationAdapter构造方法中声明为非空类型的notificationDataArrayList参数,实际传入值为null

崩溃核心堆栈

Fatal Exception: java.lang.NullPointerException
Parameter specified as non-null is null: method kotlin.jvm.internal.j.e, parameter notificationDataArrayList
触发位置:com.ls.wo.sm.ui.notifications.NotificationAdapter.<init> (NotificationAdapter.kt:17)

问题代码片段

  1. NotificationAdapter原实现
class NotificationAdapter(notificationDataArrayList:ArrayList<NotificationsData>, private val clickListener:ClickListener,
                          mcontext: Context):
        RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder>()
    {
        val notificationArrayList : ArrayList<NotificationsData>
        val mcontext : Context

        inner class NotificationViewHolder (itemView: View): RecyclerView.ViewHolder(itemView){
            val tv_notification_title : TextView
            val tv_notification_body : TextView
            val expensionBody: LinearLayout

            init {
                tv_notification_title = itemView.findViewById(R.id.til_request)
                tv_notification_body = itemView.findViewById(R.id.tv_notification_body)
                expensionBody = itemView.findViewById(R.id.layoutExpand)
            }
        }

        override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): NotificationViewHolder {
            val view : View = LayoutInflater.from(parent.context).inflate(R.layout.ui_notification_item,parent,false)
            return NotificationViewHolder(view)
        }

        override fun onBindViewHolder(holder:NotificationViewHolder,position: Int) {
            val recyclerData : NotificationsData = notificationArrayList[position]
            holder.tv_notification_title.text = recyclerData.Title
            holder.tv_notification_body.text = recyclerData.Body
            holder.itemView.setOnClickListener {
                clickListener.onItemClick(notificationArrayList[position])
            }
        }

        override fun getItemCount(): Int {
            return notificationArrayList.size
        }
        init {
            notificationArrayList = notificationDataArrayList
            this.mcontext = mcontext
        }

        interface ClickListener{
            fun onItemClick(dataModel: NotificationsData)
        }
    }
  1. Fragment中初始化Adapter的原代码
recyclerView = binding.notificationRv.apply {
    adapter = NotificationAdapter(response.body()!!.Data,this@NotificationsFragmentUI,context)
    layoutManager = manager
    adapter = adapter
}

根因定位

  1. 初始化Adapter时使用了危险的非空断言!!强取接口返回值:response.body()!!.Data。线上生产环境存在大量边缘场景:用户无通知数据、接口异常返回空结构、反序列化失败时Data字段会为null,此时!!会跳过判断直接把null值传给声明为非空的Adapter构造参数,触发Kotlin空安全校验崩溃。
  2. 测试环境无法复现的原因:Debug测试包默认关闭R8代码混淆压缩,且测试场景大多使用正常填充的测试数据,不会触发Data为null的边缘情况;Release生产包开启代码优化,线上真实用户触发null场景时直接崩溃。
  3. 初始化代码中adapter = adapter为冗余无效逻辑,无实际作用。

修复方案

  1. 移除危险的非空断言,对接口返回字段做空兜底,永远不要直接信任接口返回的数据
  2. Adapter增加空兼容逻辑,避免后续其他调用位置传入null触发崩溃
  3. 删除冗余无效代码

修复后代码

  1. Fragment中Adapter初始化逻辑
recyclerView = binding.notificationRv.apply {
    layoutManager = manager
    // 接口返回Data为null时兜底传空列表,杜绝传null给Adapter
    val notificationList = response.body()?.Data ?: arrayListOf()
    adapter = NotificationAdapter(notificationList, this@NotificationsFragmentUI, context)
}
  1. Adapter空安全优化(建议配置,从组件层面避免空指针)
class NotificationAdapter(
    notificationDataArrayList: ArrayList<NotificationsData>?,
    private val clickListener: ClickListener,
    mcontext: Context
): RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder>() {
    // 入参为null时内部兜底为空列表
    private val notificationArrayList : ArrayList<NotificationsData> = notificationDataArrayList ?: arrayListOf()
    private val mcontext : Context = mcontext

    // 其余ViewHolder、onCreateViewHolder、onBindViewHolder逻辑保持原有实现不变
    override fun getItemCount(): Int = notificationArrayList.size

    interface ClickListener{
        fun onItemClick(dataModel: NotificationsData)
    }

    // 内部NotificationViewHolder类逻辑不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:57:20