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

如何从MutableLiveData获取数据解决添加到MutableList为空问题

问题根因

LiveData的观察者回调不属于同步执行逻辑:调用observe()方法仅完成观察者注册动作,不会立刻执行回调内的代码。回调触发需要同时满足两个条件:

  • 绑定的viewLifecycleOwner处于STARTED/RESUMED的活跃生命周期状态
  • MutableLiveData持有的数据发生更新,且主线程消息队列轮询到通知事件时,才会执行回调逻辑

你写在observe()代码块外的properties.isEmpty()判断,执行时序远早于Observer回调内的add操作,所以此时列表必然为空——add操作本身是正常生效的,只是你读取列表状态的时机完全错误。

时序验证

可以通过日志直观确认执行顺序:

  1. 在observe()调用后、空判断逻辑前打一条日志
  2. 在回调内properties.add(p)执行完成后打一条日志
    运行后会看到日志输出顺序为:先执行外部空判断的日志,再执行回调内add完成的日志,完全符合异步回调的执行逻辑。
正确实现方式

所有依赖LiveData返回结果的逻辑,必须全部放在Observer回调内部处理,不要在回调外部直接访问被回调修改的变量:

properties = ArrayList()
propertyViewModel.propertyItemLiveData.observe(viewLifecycleOwner) { propertyItems ->
    // 每次回调先清空旧数据,避免重复回调导致数据重复累加
    properties.clear()
    for (property in propertyItems) {
        val p = Property(
            property.id,
            property.address,
            property.price,
            property.phone,
            property.lat,
            property.lon
        )
        properties.add(p)
    }
    // 所有依赖properties数据的逻辑全部移到回调内部
    if (properties.isEmpty()) {
        println("null")
    } else {
        // 此处执行列表刷新、UI渲染等后续逻辑
        // recyclerViewAdapter.submitList(properties)
    }
}
注意事项
  • 禁止使用Thread.sleep()等阻塞方式等待回调执行,会卡住主线程触发ANR
  • 仅在特殊场景下可以通过liveData.value同步获取当前值,该值可能为null,且无法响应后续数据更新
  • 如果数据仅用于RecyclerView渲染,不需要额外定义外层properties变量持有数据,直接在回调内处理后提交给适配器即可,减少内存冗余

内容的提问来源于stack exchange,提问作者Nguyễn Hữu Thái

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:01:12