如何解决Google Map Activity启动后自动关闭崩溃的问题?
我帮你排查了代码里几个可能导致崩溃的核心问题,咱们一步步来修复:
问题分析与修复方案
1. 修复mapFragment空指针异常
你在onCreate里定义了局部的SupportMapFragment变量,但全局的mapFragment从未被赋值,导致onRequestPermissionsResult里调用mapFragment.getMapAsync(this)时直接触发空指针崩溃。
修改代码:
把onCreate里的局部变量赋值给全局变量:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_driver_map); // 修复:将局部变量改为全局变量赋值 mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.driver_map); // 后续权限判断逻辑保持不变 if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(DriverMapActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); }else{ mapFragment.getMapAsync(this); } // 其他初始化代码... }
2. 替换过时的GoogleApiClient位置更新逻辑
GoogleApiClient的LocationServices.FusedLocationApi已经被官方废弃,继续使用会导致兼容性问题甚至崩溃,建议改用FusedLocationProviderClient的现代API实现位置更新。
修改步骤:
- 移除
GoogleApiClient相关的接口实现(GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,LocationListener) - 添加
LocationCallback处理位置更新 - 用
FusedLocationProviderClient替代旧API
核心修改代码:
// 移除原来的GoogleApiClient相关变量 // GoogleApiClient mGoogleApiClient; // Location mLastLocation; // LocationRequest mLocationRequest; // 添加位置回调 private LocationCallback mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null || getApplicationContext() == null) { return; } for (Location location : locationResult.getLocations()) { // 更新地图视角 LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); mMap.animateCamera(CameraUpdateFactory.zoomTo(11)); // 更新Firebase位置(先判断用户是否登录) FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); if (currentUser != null) { String userId = currentUser.getUid(); DatabaseReference ref = FirebaseDatabase.getInstance().getReference("DriversAvailable"); GeoFire geofire = new GeoFire(ref); geofire.setLocation(userId, new GeoLocation(location.getLatitude(), location.getLongitude())); } } } }; @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // 先检查权限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); return; } // 启用"我的位置"层 mMap.setMyLocationEnabled(true); // 获取最后已知位置并移动相机 fusedLocationClient.getLastLocation() .addOnSuccessListener(this, location -> { if (location != null) { LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude()); mMap.addMarker(new MarkerOptions().position(currentLatLng).title("我的当前位置")); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 11)); } }); // 设置位置更新参数 LocationRequest locationRequest = LocationRequest.create(); locationRequest.setInterval(1000); locationRequest.setFastestInterval(1000); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // 开始位置更新 fusedLocationClient.requestLocationUpdates(locationRequest, mLocationCallback, Looper.getMainLooper()); } @Override protected void onStop() { super.onStop(); // 停止位置更新 fusedLocationClient.removeLocationUpdates(mLocationCallback); // 移除Firebase位置(避免用户未登录时崩溃) FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); if (currentUser != null) { String userId = currentUser.getUid(); DatabaseReference ref = FirebaseDatabase.getInstance().getReference("DriversAvailable"); GeoFire geofire = new GeoFire(ref); geofire.removeLocation(userId); } }
3. 修复onStop的空指针风险
原来的代码直接调用FirebaseAuth.getInstance().getCurrentUser().getUid(),如果用户未登录(比如异常退出场景),getCurrentUser()会返回null,导致崩溃。上面的代码已经添加了用户非空判断,解决了这个问题。
4. 优化权限申请回调逻辑
确保权限通过后正确初始化地图,同时处理权限拒绝的场景:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (mapFragment != null) { mapFragment.getMapAsync(this); } } else { Toast.makeText(getApplicationContext(), "需要位置权限才能显示地图,请开启权限后重试", Toast.LENGTH_LONG).show(); finish(); // 权限拒绝时退出当前页面 } } }
这些修改主要解决了空指针异常、过时API的兼容性问题,同时优化了权限和位置更新的逻辑,应该能彻底解决你遇到的崩溃问题。
内容的提问来源于stack exchange,提问作者clinewton
相关产品推荐
相关产品推荐

