点击两次Google Map跳转按钮后应用崩溃:Kotlin空指针异常
解决KotlinNullPointerException在Google Map跳转按钮点击后的崩溃问题
看起来你遇到的问题很明确:第二次点击跳转按钮后,mMap变量为空,触发了KotlinNullPointerException,错误日志指向MyNavigationActivity.kt:261的moveCamera方法里的mMap!!.moveCamera调用。下面我来帮你分析原因并给出修复方案:
问题根源
mMap被定义为可空类型GoogleMap?,但你在代码中多处使用了非空断言!!——这种操作会在变量为空时直接抛出空指针异常。第二次点击按钮时,可能出现以下情况:
- 地图视图的生命周期状态变化(比如从后台恢复后)导致
mMap被置为null getCurrentLocation的异步回调执行时,mMap还未完成初始化(虽然第一次点击没问题,但第二次操作可能触发了重复的权限请求或地图重新加载)- 没有妥善管理MapView的生命周期,导致地图实例被回收
修复步骤
1. 替换非空断言!!为安全调用?.
首先修改moveCamera方法,避免直接强制非空:
private fun moveCamera(latLng: LatLng, zoom: Float) { mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom)) ?: run { // 给用户提示地图未准备好 Toast.makeText(this, "地图加载中,请稍后重试", Toast.LENGTH_SHORT).show() } }
2. 确保仅在地图初始化完成后执行操作
添加一个标记位跟踪地图是否准备就绪,避免在地图未加载完成时触发操作:
private var isMapReady = false override fun onMapReady(googleMap: GoogleMap?) { mapView.onResume() mMap = googleMap isMapReady = true // 标记地图已初始化完成 askPermissionLocation() // ... 你的其他代码 } // 修改按钮点击事件 B_search.setOnClickListener { if (isMapReady) { searchArea() } else { Toast.makeText(this, "地图正在加载,请稍候", Toast.LENGTH_SHORT).show() } }
3. 在异步回调中检查mMap状态
在getCurrentLocation的回调里,先确认mMap不为空再执行后续操作:
override fun onComplete(loc: Task<Location>) { if (loc.isSuccessful) { val currentLocation = loc.result as Location? if (currentLocation != null && mMap != null) { moveCamera( LatLng(currentLocation.latitude, currentLocation.longitude), DEFAULT_ZOOM ) latitude = currentLocation.latitude longitude = currentLocation.longitude } else if (mMap == null) { Toast.makeText(this@MyNavigationActivity, "地图未准备好,请稍后再试", Toast.LENGTH_SHORT).show() } } else { askPermissionLocation() } }
4. 完善MapView的生命周期管理
MapView需要和Activity的生命周期同步,否则可能导致地图实例被回收。添加以下生命周期方法:
override fun onResume() { super.onResume() mapView.onResume() } override fun onPause() { super.onPause() mapView.onPause() } override fun onDestroy() { super.onDestroy() mapView.onDestroy() } override fun onLowMemory() { super.onLowMemory() mapView.onLowMemory() }
额外优化建议
- 在
searchArea方法中,也对mMap使用安全调用?.,比如mMap?.addMarker(markerOptions),避免同样的空指针问题 - 考虑使用
lateinit替代可空类型,但要确保mMap在使用前一定被初始化(不过MapView的异步初始化特性,用可空类型加安全调用更稳妥)
内容的提问来源于stack exchange,提问作者erem149
相关产品推荐
相关产品推荐

