如何从MutableLiveData获取数据解决添加到MutableList为空问题
问题根因
LiveData的观察者回调不属于同步执行逻辑:调用observe()方法仅完成观察者注册动作,不会立刻执行回调内的代码。回调触发需要同时满足两个条件:
- 绑定的
viewLifecycleOwner处于STARTED/RESUMED的活跃生命周期状态 MutableLiveData持有的数据发生更新,且主线程消息队列轮询到通知事件时,才会执行回调逻辑
你写在observe()代码块外的properties.isEmpty()判断,执行时序远早于Observer回调内的add操作,所以此时列表必然为空——add操作本身是正常生效的,只是你读取列表状态的时机完全错误。
时序验证
可以通过日志直观确认执行顺序:
- 在
observe()调用后、空判断逻辑前打一条日志 - 在回调内
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
相关产品推荐
相关产品推荐

