GeoFire调用removeAllListeners()未生效 onKeyEntered仍持续触发
问题核心原因
- GeoFire的事件分发机制决定了:初始查询阶段,所有命中查询范围的key对应的
onKeyEntered回调是同步批量排入执行队列的,不会在单次回调执行时动态中断队列中已经排好的后续回调。 - 代码中在达到阈值时调用的
geoQuery.removeAllListeners(),仅会移除GeoQuery后续对数据库位置变更事件的监听(比如后续有用户移动进入查询范围时的实时事件),但无法阻断当前批次已经计算完成、即将同步触发的存量onKeyEntered回调,因此会出现“明明移除了监听,onKeyEntered还是一直触发直到读完全量数据”的现象。
修复方案
- 不要把
removeAllListeners()当成中断当前批次回调的开关,要在onKeyEntered的最开头增加阈值判断,拦截所有阈值触发后残留的无效回调:- 回调进入后先检查
pagingCounter是否已经达到设定阈值,如果达到直接返回,不执行任何业务逻辑 - 仅当计数累加后首次达到阈值时,调用
removeAllListeners()阻断后续新增的动态位置事件
- 回调进入后先检查
- 核心逻辑修改示例:
override fun onKeyEntered(key: String?, location: GeoLocation?) { // 优先拦截阈值触发后的所有残留回调 if (pagingCounter >= 100) return pagingCounter++ // 首次达到阈值时,移除监听阻断后续动态事件 if (pagingCounter >= 100) { geoQuery.removeAllListeners() } }
- 额外适配注意:
onGeoQueryReady中遍历键集合加载用户详情的逻辑,需要和分页停止的逻辑做联动校验,避免因为提前停止计数导致重复加载或者无效加载,造成网络和内存开销浪费。
内容的提问来源于stack exchange,提问作者marsuser
相关产品推荐
相关产品推荐

