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

MapView中Retrofit异步加载后ArrayList读取时机异常求助

解决Retrofit异步请求导致Marker数据未加载的问题

我来帮你搞定这个问题——你遇到的是异步请求的时序问题:Retrofit的enqueue()方法是在后台线程执行网络请求的,调用getd("all")后,你的代码会立刻跳到后面的循环去遍历mker集合,但此时网络请求还没完成,mker还是空的,自然什么都读不到。

核心解决方案:把Marker操作移到异步回调里

网络请求的结果只有在onResponse()回调方法里才能确保已经获取到,所以必须把遍历集合、创建Marker的逻辑放到这个回调内部,或者通过单独的方法来处理加载完成的数据。

修改后的完整代码示例

首先调整onMapReady(),只负责初始化地图和发起请求:

public void onMapReady(GoogleMap googleMap) { 
    map = googleMap; 
    // 先发起数据请求,不着急处理Marker
    getd("all"); 
}

然后更新getd()方法,在请求成功后再处理Marker:

private void getd(String selector){ 
    Retrofit retrofit = new Retrofit.Builder() 
        .baseUrl(Api.BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 
    Api api = retrofit.create(Api.class); 
    Call<List<col>> call = api.getHeroes(selector); 
    call.enqueue(new Callback<List<col>>() { 
        @Override 
        public void onResponse(Call<List<col>> call, Response<List<col>> response) { 
            // 先判断请求是否成功、返回数据是否为空
            if (response.isSuccessful() && response.body() != null) {
                ArrayList<MarkerData> mker = new ArrayList<>(); 
                List<col> colList = response.body();
                
                // 遍历接口返回的数据,存入集合
                for (col c : colList){ 
                    Log.d("name : ",c.getNom_col()); 
                    Log.d("Lat : ",c.getLat_col()); 
                    Log.d("Long : ",c.getLong_col()); 
                    Log.d("Email : ",c.getEmailcol()); 
                    Log.d("type : ",c.getType()); 
                    Log.d("date : ",c.getDate_creation_col()); 
                    Log.d("Creator : ",c.getCreator()); 
                    mker.add(new MarkerData(c.getNom_col(),c.getLat_col(),c.getLong_col(),c.getEmailcol(),c.getType(),c.getDate_creation_col(),c.getCreator())); 
                }
                
                // 数据准备完毕,现在处理Marker的创建和遍历
                processMapMarkers(mker);
            } else {
                // 处理请求失败或空数据的情况
                Log.e("API Error", "请求失败或返回空数据");
            }
        }

        @Override
        public void onFailure(Call<List<col>> call, Throwable t) {
            // 别忘了处理网络请求失败的场景(比如无网、服务器挂了)
            Log.e("Network Error", "网络请求失败:" + t.getMessage());
        }
    }); 
}

// 把Marker的处理逻辑单独抽出来,代码更清晰
private void processMapMarkers(ArrayList<MarkerData> mker) {
    for(int i = 0 ; i < mker.size() ; i++) { 
        Log.d("Date of arrays", mker.get(i).getDate()); 
        // 在这里添加创建Marker的核心代码,比如:
        // LatLng shopPosition = new LatLng(mker.get(i).getLat_col(), mker.get(i).getLong_col());
        // Marker marker = map.addMarker(new MarkerOptions()
        //         .position(shopPosition)
        //         .title(mker.get(i).getNom_col()));
        // 如果需要后续移除Marker,可以把创建的Marker也存入一个集合保存
    }
}

几个关键注意点

  • 必须处理onFailure():网络请求不可能100%成功,这里可以加个Toast提示用户,或者做重试逻辑。
  • 空指针防护:一定要检查response.isSuccessful()和response.body() != null,避免接口返回错误码或者空数据导致崩溃。
  • 代码解耦:把Marker处理逻辑抽到单独的方法里,不仅可读性更高,后续要修改Marker样式或者逻辑时也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:32:47