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

StateFlow传递null致非null类型转换失败,RecyclerView适配异常

问题根源

  1. 不安全的强制转换:it?.categories as List<Category> 会在 StateFlow 初始值为null时触发ClassCastException,此时it?.categories为null,无法强制转为非空列表,导致后续有效数据无法正常传递给Adapter。
  2. Adapter数据更新逻辑漏洞:setData仅调用addAll未清空旧数据,多次更新会导致列表重复;同时categoryList声明为可空类型,与传入的非空列表不匹配,增加无效的可空性处理。
  3. 数据流收集未绑定生命周期:直接用lifecycleScope.launch收集数据流,Activity后台时仍会持续收集,存在内存泄漏风险。

修复方案

1. 修复MainActivity数据流收集逻辑

替换强制转换为安全的空值判断,同时绑定生命周期避免内存泄漏:

lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.categories.collect {
            it?.categories?.let { categories ->
                adapter.setData(categories)
            }
            Log.d(TAG, "onCreate: ${it?.categories}")
        }
    }
}

2. 优化CategoryAdapter数据处理

  • 调整列表为非空类型,移除不必要的可空性;
  • 修改setData先清空旧数据再添加新数据,避免重复:
class CategoryAdapter(private val context: Context?) :
    RecyclerView.Adapter<CategoryAdapter.CategoryViewHolder>() {
    private var categoryList: MutableList<Category> = mutableListOf()

    inner class CategoryViewHolder(itemView: CategoryLayoutBinding) :
        RecyclerView.ViewHolder(itemView.root) {
        val name = itemView.categoryNameTv
        val img = itemView.categoryIv
        val des = itemView.categoryDesTv
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder {
        val binding = CategoryLayoutBinding.inflate(LayoutInflater.from(context), parent, false)
        return CategoryViewHolder(binding)
    }

    override fun onBindViewHolder(holder: CategoryViewHolder, position: Int) {
        val category = categoryList[position]
        holder.name.text = category.strCategory
        holder.des.text = category.strCategoryDescription
        Glide.with(context as Context).load(category.strCategoryThumb).into(holder.img)
    }

    override fun getItemCount(): Int {
        return categoryList.size
    }

    fun setData(categoryList: List<Category>) {
        this.categoryList.clear()
        this.categoryList.addAll(categoryList)
        notifyDataSetChanged()
    }
}

3. 可选:优化ViewModel的StateFlow初始值

如果API返回的CategoryResponse不会为空,可将StateFlow改为非空类型,进一步减少空值处理:

private val _categories: MutableStateFlow<CategoryResponse> = MutableStateFlow(CategoryResponse())
val categories: StateFlow<CategoryResponse> = _categories

修改后即可确保数据正常传递给Adapter,RecyclerView能正确展示分类列表。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:01:15