骑手应用二次启动后Google Maps司机Marker不显示问题
问题分析与解决方案
核心问题
Constants是全局单例对象,其中的marketList和driversFound集合会在应用进程存活期间保留第一次启动时的数据:
- 第二次启动时,
marketList中存储的是旧GoogleMap实例创建的Marker,这些Marker无法在新的Map实例上显示 - 旧的
driversFound数据未清空,导致逻辑判断错误,不会重新添加新的Marker
修复步骤
1. 清空全局集合的时机
在HomeFragment的init方法开头,清空全局集合避免旧数据干扰:
private fun init() { // 清空全局集合,消除上次启动的残留数据 Constants.marketList.clear() Constants.driversFound.clear() iFirebaseDriverLocationListener = this // ... 原有代码逻辑 }
2. 移除错误的IO协程
addDriverMarker中使用Dispatchers.IO是错误的,GoogleMap相关操作必须在主线程执行:
private fun addDriverMarker() { Log.d("MarkerDebug", "addDriverMarker is called ") if (Constants.driversFound.isNotEmpty()) { val newDriverKeys = Constants.driversFound.mapNotNull { it.key } val existingDriverKeys = Constants.marketList.keys // 移除不在当前列表中的司机Marker val removedDriverKeys = existingDriverKeys.subtract(newDriverKeys.toSet()) for (key in removedDriverKeys) { Constants.marketList[key]?.remove() Constants.marketList.remove(key) } // 新增或更新司机Marker Constants.driversFound.forEach { driverGeoModel -> findDriverByKey(driverGeoModel) Log.d("MarkerDebug", "addDriverMarker is called when found driver: ${driverGeoModel.key}") } Snackbar.make( requireView(), getString(R.string.drivers_are_found), Snackbar.LENGTH_SHORT ).show() } else { // 清空所有Marker Constants.marketList.values.forEach { it.remove() } Constants.marketList.clear() Snackbar.make( requireView(), getString(R.string.drivers_are_not_found), Snackbar.LENGTH_SHORT ).show() } }
3. 修复cityName变量作用域问题
loadAvailableDrivers中局部cityName覆盖成员变量,导致onDriverInfoLoadSuccess无法获取正确城市名:
// 在loadAvailableDrivers方法中,将局部变量赋值改为成员变量赋值 // val cityName = addressList!![0].locality this.cityName = addressList!![0].locality
4. 重置firstTime标记
在onDestroyView中重置firstTime,避免多次启动后位置判断逻辑异常:
override fun onDestroyView() { super.onDestroyView() fusedLocationProviderClient.removeLocationUpdates(locationCallback) _binding = null firstTime = true // 重置首次位置标记 }
额外优化建议
- 避免用全局单例存储UI相关对象(如Marker),建议将这些集合放在Fragment或ViewModel中管理
- 所有GoogleMap操作必须在主线程执行,禁止在IO线程调用Map相关API
- 在Fragment生命周期的销毁阶段清理资源,避免内存泄漏
内容的提问来源于stack exchange,提问作者Dan Murphyy
相关产品推荐
相关产品推荐

