You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio方法执行顺序问题致应用崩溃求助

问题解答:AsyncTask/线程无法解决你的崩溃问题,核心要调整异步流程

你的崩溃根源有两个:

  • fetchLastLocation(含权限请求、定位获取)是异步操作,但你在onCreate里同时触发了地图初始化getMapAsync,导致地图回调onMapReady先执行时,currentLocation还未赋值,直接调用getLatitude()引发空指针。
  • 未开启设备定位时,getLastKnownLocation返回null,onMapReady里没有空判断就直接调用定位方法,导致崩溃。

AsyncTask或线程完全没必要,也解决不了问题——因为问题本质是异步任务的执行顺序依赖,不是线程执行效率的问题。下面是直接有效的修复方案:


关键修复步骤

1. 让地图初始化依赖定位准备完成

移除onCreate中直接调用的getMapAsync,只在成功获取到定位(或确认定位权限、GPS状态后)再初始化地图:

修改onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    client = LocationServices.getFusedLocationProviderClient(this);
    LManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    // 先不初始化地图,等待定位准备就绪
    fetchLastLocation();
}

新增单独的地图初始化方法,并修改fetchLastLocation:

private void fetchLastLocation() {
    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}, REQUEST_CODE);
        CheckGps();
        return;
    }
    // 先确认GPS状态
    CheckGps();
    Task<Location> task = client.getLastLocation();
    task.addOnSuccessListener(new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            if (location != null) {
                currentLocation = location;
                initMap(); // 拿到有效定位后初始化地图
            } else {
                // 尝试获取最后已知位置
                currentLocation = getLastKnownLocation();
                if(currentLocation != null){
                    initMap();
                } else {
                    Toast.makeText(MainActivity.this, "无法获取定位,请检查GPS是否开启", Toast.LENGTH_LONG).show();
                }
            }
        }
    });
}

// 单独的地图初始化方法
private void initMap(){
    suppMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.maps);
    suppMapFragment.getMapAsync(this);
}

2. 在onMapReady中强制做空安全判断

即使定位逻辑出现意外,也要避免空指针崩溃:

@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
    this.mMap = googleMap;
    googleMap.getUiSettings().setMyLocationButtonEnabled(true);
    
    // 权限判断修正:之前的逻辑写反了,应该是有权限时才开启我的位置
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        googleMap.setMyLocationEnabled(true);
    }

    // 空安全判断:没有定位时直接返回并提示
    if(currentLocation == null){
        Toast.makeText(this, "定位未就绪,请稍后重试", Toast.LENGTH_SHORT).show();
        return;
    }

    LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
    MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("你在这里!");
    googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 12));
    googleMap.addMarker(markerOptions);
}

3. 优化权限回调后的逻辑

确保用户授予权限后,重新触发定位获取和地图初始化:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                fetchLastLocation(); // 权限授予后重新获取定位,自动触发地图初始化
            } else {
                Toast.makeText(this, "需要定位权限才能显示你的位置", Toast.LENGTH_SHORT).show();
            }
            break;
    }
}

为什么AsyncTask/线程没用?

fetchLastLocation本身就是基于Google Play Services的异步任务,用线程或AsyncTask包裹它,只是多了一层线程切换,无法改变“地图初始化和定位获取并行执行”的问题。只有让地图初始化的触发依赖定位任务的完成回调,才能从根本上避免时序问题导致的崩溃。

内容的提问来源于stack exchange,提问作者user21605117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 16:32:01