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

Codename One parseJSON模拟器正常手机端空指针异常咨询

问题描述

以下基于Java的Codename One代码可在Simulator中成功运行,但在实体手机上运行失败,代码已添加行号:

58 Map<String, Object> pageMap = null;
    59 ConnectionRequest connectionRequest = new ConnectionRequest();
    60 connectionRequest.setUrl("https://api.beta.tab.com.au/v1/tab-info-service/racing/dates/today/meetings");
    61 connectionRequest.setPost(false);
    62 connectionRequest.addArgument("jurisdiction", "QLD");
    63 NetworkManager.getInstance().addToQueueAndWait(connectionRequest);
    64 try {
    65     Dialog.show("Trace", "pre parseJSON", "OK", "");
    66     pageMap = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(connectionRequest.getResponseData()), "UTF-8"));
    67     Dialog.show("Trace", "post parseJSON", "OK", "");
    68     if (pageMap == null) {
    69         Dialog.show("Trace", "pageMap is null!", "OK", "");
    70     } else {
    71         Dialog.show("Trace", "pageMap is NOT null,pageMap," + pageMap.toString().substring(0, 200), "OK", "");
    72     }
    73 } catch (Exception e) {
    74     Dialog.show("Trace", "getPageMap,exception," + e, "OK", "");
    75 }
  • 代码中的Trace弹窗是用于获取手机端运行状态的调试手段。
  • Simulator环境下运行时,pageMap可正常赋值输出,示例内容为{meetings=[{meetingName=DOOMBEN, location=QLD...}。
  • 实体手机端运行时,第65行pre parseJSON、第67行post parseJSON弹窗均可正常弹出,执行第68行判断逻辑时触发异常,第74行弹窗展示的异常信息为:java.lang.NullPointerException: Attempt to read from field 'java.util.LinkedHashMap$LinkedHashMapEntry java.util.LinkedHashMap.head' on a null object reference。
  • 该段代码在2022年4月16日的历史构建版本中可正常运行,提问者怀疑相关API存在变更,请求协助排查。
问题原因与解决方案

该问题不是公开API变更导致,核心是旧版Codename One JSON解析逻辑在移动端的兼容bug,以及写法上的跨平台隐患:

  1. post parseJSON弹窗正常弹出仅代表parseJSON方法执行完成没有抛出同步异常,不代表返回值是合法初始化的Map实例。Android端ART虚拟机和桌面Simulator用的JVM类加载、对象初始化逻辑存在差异,旧版JSONParser在通过多层流嵌套解析响应时,会出现对象返回但内部LinkedHashMap结构未完成初始化的情况,后续访问Map内容(包括toString()、key遍历、隐式结构检查)时就会抛出你看到的head字段空指针。
  2. 嵌套ByteArrayInputStream+InputStreamReader的解析写法在移动端部分版本存在编码转换兼容问题,会导致解析结果异常,Simulator因为用的是桌面JVM的流实现,不会触发该问题。

按以下步骤修改即可修复:

  • 第一步,解析前先把响应数据转成UTF-8字符串,校验数据完整性,同时规避流嵌套的兼容问题:
byte[] respData = connectionRequest.getResponseData();
// 先判断响应数据本身是否为空
if (respData == null || respData.length == 0) {
    Dialog.show("Error", "Network response is empty", "OK", "");
    return;
}
String respStr = new String(respData, "UTF-8");
  • 第二步,用StringReader做JSON解析,解析后先做类型校验再使用:
JSONParser parser = new JSONParser();
Object parseResult = parser.parseJSON(new StringReader(respStr));
// 先判断类型和空值,不要直接强转接Map
if (!(parseResult instanceof Map)) {
    Dialog.show("Trace", "Parse result is not valid Map, type: " + (parseResult == null ? "null" : parseResult.getClass().getName()), "OK", "");
    return;
}
pageMap = (Map<String, Object>) parseResult;
// 后续再做key存在性校验、业务逻辑处理
if (pageMap.containsKey("meetings")) {
    // 正常业务逻辑
}
  • 额外注意:addToQueueAndWait会阻塞调用线程,如果这段代码不是写在EDT事件线程上,阻塞等待可能导致网络响应数据读取不完整,建议优先使用带回调的addToQueue方法异步处理网络请求,规避线程阻塞带来的隐性异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:12:51