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

使用非Google Places API的JSON服务查询附近地点及空指针错误修复

错误根源

你在ParserTask的onPostExecute方法中调用了空对象的size()方法,本质是JSON解析逻辑出错返回了null,加上没有做非空校验导致崩溃。

具体问题点

  • JSON层级读取错误:接口返回的根对象下首先是ArrayOfmasjid节点,你当前parseResult方法直接从根对象读取masjid数组,必然抛出JSON异常,最终返回null列表
  • HashMap键名冲突:你把纬度和经度都存在了__text同一个key下,后续的经度会直接覆盖纬度值,就算解析成功也拿不到正确的经纬度
  • 数组遍历错误:parseJsonArray方法的循环中你写死了jsonArray.get(1),每次都读取数组第二个元素,要么逻辑错误要么触发数组越界异常
  • 缺失非空校验:onPostExecute拿到解析结果后直接调用size(),同时没有判断map对象是否完成初始化(getMapAsync是异步回调,有可能接口请求完了地图还没加载好)

修复代码

修复后的JsonParser类

public class JsonParser {
    private HashMap<String, String> parseJsonObject(JSONObject object) {
        HashMap<String, String> datalist = new HashMap<>();
        try {
            String name = object.getString("masjidName");
            String latitude = object.getJSONObject("masjidLocation")
                    .getJSONObject("coordinates")
                    .getJSONArray("double")
                    .getJSONObject(1)
                    .getString("__text");
            String longitude = object.getJSONObject("masjidLocation")
                    .getJSONObject("coordinates")
                    .getJSONArray("double")
                    .getJSONObject(0)
                    .getString("__text");
            datalist.put("name",name);
            datalist.put("latitude",latitude); // 改用不同的key存经纬度
            datalist.put("longitude",longitude);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return datalist;
    }
    private List<HashMap<String,String>> parseJsonArray(JSONArray jsonArray){
        List<HashMap<String,String>> datalist = new ArrayList<>();
        if (jsonArray == null) return datalist; // 空数组直接返回空列表
        for (int i = 0; i< jsonArray.length(); i++){
            try {
                HashMap<String,String> data = parseJsonObject((JSONObject) jsonArray.get(i)); // 改为用循环变量i取值
                datalist.add(data);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return datalist;
    }
    public List<HashMap<String, String>> parseResult(JSONObject object){
        JSONArray jsonArray = null;
        try {
            // 先取ArrayOfmasjid节点,再取里面的masjid数组
            jsonArray = object.getJSONObject("ArrayOfmasjid").getJSONArray("masjid");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return parseJsonArray(jsonArray);
    }
}

修复后的ParserTask的onPostExecute方法

@Override
protected void onPostExecute(List<HashMap<String, String>> hashMaps) {
    // 先校验map和hashMaps都不为空再执行后续逻辑
    if (map == null || hashMaps == null) return;
    map.clear();
    for (int i=0; i<hashMaps.size();i++){
        HashMap<String,String> hashMapList = hashMaps.get(i);
        double lat = Double.parseDouble(hashMapList.get("latitude"));
        double lng = Double.parseDouble(hashMapList.get("longitude"));
        String name = hashMapList.get("name");
        LatLng latLng = new LatLng(lat,lng);
        MarkerOptions options = new MarkerOptions();
        options.position(latLng);
        options.title(name);
        map.addMarker(options);
    }
}

额外优化建议

  • 权限申请通过后再触发接口请求,你现在不管权限有没有同意都直接执行new PlaceTask().execute(url),逻辑不合理
  • 接口请求可以放在位置获取成功之后,后续可以换成传入当前经纬度查询附近地点,而不是写死查询邮编462001的地点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:57:01