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

Android:等待Volley响应完成后再执行后续代码

解决Volley异步请求导致标记点数据为空的问题

这问题我太熟了——Volley的异步特性就是新手容易踩的坑!你现在的问题本质是:Volley的网络请求在后台线程执行,主线程不会等待请求完成就继续往下走,所以你刚调用完getMarkers()就去依赖latLng执行后续逻辑时,数据还没加载完成,自然会拿到空值。

核心解决方案:利用Volley的回调机制延迟执行后续代码

Volley本身就设计了onResponse和onErrorResponse回调,我们要把所有依赖标记点数据的逻辑,放到请求成功的回调里执行,确保只有当数据真正加载完成后,才去处理地图标记点。

方案1:直接在回调中处理(最简单直接)

修改你的getMarkers()方法,把添加标记点到地图的逻辑移到onResponse里面:

public void getMarkers(){ 
    requestQueue = Volley.newRequestQueue(getApplicationContext()); 
    // 替换成你的实际请求URL
    String url = "你的JSON数据接口地址";
    
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
        Request.Method.GET, 
        url, 
        null, 
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                // 这里解析JSON,获取latLng数据(示例逻辑,根据你的实际JSON结构调整)
                List<LatLng> markerPoints = new ArrayList<>();
                try {
                    JSONArray markersArray = response.getJSONArray("markers");
                    for (int i = 0; i < markersArray.length(); i++) {
                        JSONObject markerObj = markersArray.getJSONObject(i);
                        double lat = markerObj.getDouble("latitude");
                        double lng = markerObj.getDouble("longitude");
                        markerPoints.add(new LatLng(lat, lng));
                    }
                    
                    // 关键:把需要用到标记点的代码放在这里!
                    // 比如调用添加标记点到地图的方法
                    addMarkersToMap(markerPoints);
                    
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "数据解析失败", Toast.LENGTH_SHORT).show();
                }
            }
        }, 
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // 处理请求失败的情况,给用户提示
                Toast.makeText(getApplicationContext(), "加载标记点数据失败", Toast.LENGTH_SHORT).show();
            }
        });
    
    requestQueue.add(jsonObjectRequest);
    // 注意:这里不要再调用依赖latLng的方法,因为请求还没完成!
}

// 示例:添加标记点到地图的方法
private void addMarkersToMap(List<LatLng> markerPoints) {
    for (LatLng point : markerPoints) {
        mMap.addMarker(new MarkerOptions().position(point));
    }
}

方案2:用接口回调解耦逻辑(适合复杂场景)

如果你的代码结构比较复杂,或者需要在多个地方复用标记点加载逻辑,可以定义一个回调接口,把数据传递出去:

  1. 先定义回调接口:
public interface OnMarkersLoadedListener {
    void onMarkersLoaded(List<LatLng> markers);
    void onLoadFailed(String errorMsg);
}
  1. 修改getMarkers()方法,接收回调接口:
public void getMarkers(OnMarkersLoadedListener listener){ 
    requestQueue = Volley.newRequestQueue(getApplicationContext()); 
    String url = "你的JSON数据接口地址";
    
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
        Request.Method.GET, 
        url, 
        null, 
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                List<LatLng> markerPoints = new ArrayList<>();
                try {
                    JSONArray markersArray = response.getJSONArray("markers");
                    for (int i = 0; i < markersArray.length(); i++) {
                        JSONObject markerObj = markersArray.getJSONObject(i);
                        double lat = markerObj.getDouble("latitude");
                        double lng = markerObj.getDouble("longitude");
                        markerPoints.add(new LatLng(lat, lng));
                    }
                    // 数据加载完成,通过回调传递出去
                    listener.onMarkersLoaded(markerPoints);
                } catch (JSONException e) {
                    e.printStackTrace();
                    listener.onLoadFailed("数据解析失败:" + e.getMessage());
                }
            }
        }, 
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onLoadFailed("网络请求失败:" + error.getMessage());
            }
        });
    
    requestQueue.add(jsonObjectRequest);
}
  1. 调用getMarkers()时传入回调:
getMarkers(new OnMarkersLoadedListener() {
    @Override
    public void onMarkersLoaded(List<LatLng> markers) {
        // 在这里处理标记点加载后的逻辑
        addMarkersToMap(markers);
    }

    @Override
    public void onLoadFailed(String errorMsg) {
        Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_SHORT).show();
    }
});

额外提醒

  • 解析JSON的操作如果数据量很大,建议放到后台线程处理(比如用AsyncTask或者Kotlin协程),避免阻塞主线程导致界面卡顿。
  • 记得在Activity/Fragment销毁时,取消Volley的请求,防止内存泄漏:requestQueue.cancelAll(this);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:31:51