DistanceTo应用运行崩溃:MapsActivity空对象引用报错与距离计算代码关联疑问
这个问题我之前也碰到过!核心原因其实是你的距离计算代码间接触发了GoogleMap的操作,但此时Map还没完成初始化,导致空指针崩溃。咱们一步步拆解:
1. 报错的直接原因
你看到的报错:
Attempt to invoke virtual method 'com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)' on a null object reference
本质就是GoogleMap对象还没被初始化(值为null),你就调用了它的addMarker()方法。而GoogleMap的初始化是异步的——必须等到onMapReady()回调触发后,才能拿到可用的实例。
2. 距离计算代码为什么会关联崩溃?
你注释掉距离计算代码就正常,说明这段代码里一定有依赖GoogleMap的逻辑:
- 可能是计算完距离后,你尝试在地图上添加标记显示两个GPS位置;
- 或者计算逻辑里间接调用了其他需要操作地图的方法;
- 而你调用这段距离计算代码的时机太早(比如在
onCreate()、onStart()里),这时候GoogleMap还没准备好,自然就空指针了。
3. 具体解决步骤
步骤一:确保GoogleMap在onMapReady()中初始化
先把GoogleMap实例的初始化放在回调里,这是操作地图的安全时机:
private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); // 获取MapFragment,注册回调 SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); // 这里会触发onMapReady回调 } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // 到这里,mMap才是可用的!把距离计算逻辑移到这里调用 calculateAndShowDistance(); }
步骤二:给距离计算代码加非空判断
如果你的距离计算逻辑里有操作地图的代码,一定要先检查mMap是否不为null:
private void calculateAndShowDistance() { // 先判断map是否初始化完成 if (mMap == null) { Log.e("MapsActivity", "GoogleMap还没初始化完成!"); return; } // 你的GPS位置获取逻辑 LatLng location1 = new LatLng(39.9042, 116.4074); // 示例位置1 LatLng location2 = new LatLng(31.2304, 121.4737); // 示例位置2 // 计算距离(用Google Maps Utils的工具类,或者自己实现) float distanceInMeters = SphericalUtil.computeDistanceBetween(location1, location2); // 操作地图(这时候mMap已经不为null了) mMap.addMarker(new MarkerOptions().position(location1).title("起点")); mMap.addMarker(new MarkerOptions().position(location2).title("终点")); // 可以添加距离显示的逻辑,比如在地图上画折线或者显示文本 }
步骤三:排查调用时机
检查你原来调用距离计算代码的地方,是不是在onCreate()、onResume()这类生命周期方法里?这些方法执行时,MapFragment还在异步加载GoogleMap,此时调用依赖Map的代码必然会空指针。所有操作地图的逻辑都必须放在onMapReady()之后。
4. 补充提醒
不要误以为布局里加了MapFragment,GoogleMap就立刻可用。MapFragment的加载是异步的,必须等待onMapReady()回调确认后,才能安全地调用任何GoogleMap的方法。
内容的提问来源于stack exchange,提问作者captindfru

