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

MapView中Retrofit异步加载数据后遍历ArrayList时机错误问题求助

解决异步数据加载导致的Marker遍历空列表问题

这是个非常典型的异步操作时序问题,我来帮你梳理清楚怎么解决~

问题根源

你遇到的核心问题是Retrofit的enqueue()是异步执行的:当你在onMapReady里调用getd("all")后,代码会立刻往下执行遍历mker的循环,但这时候接口请求还在后台网络请求阶段,onResponse回调还没触发,mker里完全没有数据,所以循环自然什么都做不了。

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

要确保只有在数据加载完成后,才去遍历列表、创建Marker,我们需要把相关逻辑移到onResponse回调中,同时调整变量的作用域,让各个方法都能访问到mker和map。

步骤1:调整成员变量

先把mker和map定义为类的成员变量,这样在回调里也能访问到:

// 类成员变量:保存Marker数据和地图实例
private ArrayList<MarkerData> mker = new ArrayList<>();
private GoogleMap map;

步骤2:简化onMapReady方法

onMapReady只需要初始化地图并发起数据请求即可:

public void onMapReady(GoogleMap googleMap) {
    map = googleMap;
    // 发起异步数据请求
    getd("all");
}

步骤3:在onResponse中处理Marker逻辑

修改getd方法的onResponse回调,在数据填充完成后再遍历列表、创建Marker:

private void getd(String selector){
    // 可以在这里显示加载对话框(如果需要)
    // ProgressDialog progress = new ProgressDialog(getActivity());
    // progress.setTitle("Charger les infos");
    // progress.setMessage("attendre...");
    // progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    // progress.show();

    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) {
            // 关闭加载对话框(如果显示了的话)
            // progress.dismiss();
            
            mker.clear(); // 先清空旧数据,避免重复添加
            List<col> colList = response.body();
            
            // 处理空数据情况,避免空指针
            if (colList == null) {
                Log.d("Retrofit", "接口返回数据为空");
                return;
            }
            
            // 填充Marker数据并创建地图Marker
            for (col c: colList){
                Log.d("name : ",c.getNom_col());
                Log.d("Lat : ",c.getLat_col());
                Log.d("Long : ",c.getLong_col());
                // ... 其他日志输出
                
                // 添加数据到mker
                MarkerData markerData = new MarkerData(
                    c.getNom_col(),
                    c.getLat_col(),
                    c.getLong_col(),
                    c.getEmailcol(),
                    c.getType(),
                    c.getDate_creation_col(),
                    c.getCreator()
                );
                mker.add(markerData);
                
                // 创建并添加Marker到地图
                Marker marker = map.addMarker(new MarkerOptions()
                        .position(new LatLng(
                            Double.parseDouble(c.getLat_col()), 
                            Double.parseDouble(c.getLong_col())
                        ))
                        .title(c.getNom_col())
                );
                // 可选:把Marker和MarkerData关联,方便后续移除操作
                markerData.setMarker(marker); // 需要给MarkerData添加setMarker方法
            }
            
            // 现在遍历mker是有效的,数据已经全部填充完成
            for(int i = 0 ; i < mker.size() ; i++) {
                Log.d("Date of arrays", mker.get(i).getDate());
            }
        }

        @Override
        public void onFailure(Call<List<col>> call, Throwable t) {
            // 网络请求失败时的处理:关闭对话框、打印错误日志
            // progress.dismiss();
            Log.e("Retrofit", "请求失败:" + t.getMessage());
        }
    });
}

后续移除Marker的思路

因为mker是类成员变量,你可以随时访问它保存的MarkerData。如果之前把Marker对象关联到了MarkerData里(比如上面的markerData.setMarker(marker)),后续要移除Marker时,只需要遍历mker,调用marker.remove()即可:

// 移除所有Marker的示例
for (MarkerData data : mker) {
    if (data.getMarker() != null) {
        data.getMarker().remove();
    }
}
mker.clear();

额外注意事项

  • 确保getLat_col()和getLong_col()返回的字符串可以正确转成double,如果有格式问题需要做异常处理;
  • 不要忘记实现onFailure回调,处理网络请求失败的情况;
  • 如果需要多次请求数据,每次请求前记得清空mker和地图上的旧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 10:32:42