使用MPAndroidChart时触发java.lang.NumberFormatException问题求助
问题分析与解决方案
问题根源
从栈追踪信息可以明确看到:Gson在解析API响应时,试图将字符串格式的时间值(如"20:36:00")转换为long类型,导致NumberFormatException。原因是:
- 后端API返回的
time字段是Time类型的字符串(格式为HH:mm:ss) - 你在Android端的
SaunaBit类中,将time定义为long类型,Gson无法自动完成字符串到长整型的转换
解决方案
提供两种可行的解决思路,根据你的实际情况选择:
方案1:修改Android端的类型处理(无需改动后端)
更新数据模型类
将SaunaBit中的time字段类型从long改为String:public static class SaunaBit { public String sauna_name; public String time; // 改为String类型 public float temp; public float co2; public float humidity; }将时间字符串转换为MPAndroidChart可用的数值
在AddCurrentDataValues方法中,把HH:mm:ss格式的字符串转换为一天中的秒数(作为折线图的X轴数值):private void AddCurrentDataValues() { saunaDataAPI.getHistoricalData("Sauna1").enqueue(new Callback<List<SaunaBitResponse.SaunaBit>>() { @Override public void onResponse(@NonNull Call<List<SaunaBitResponse.SaunaBit>> call, @NonNull Response<List<SaunaBitResponse.SaunaBit>> response) { ArrayList<Entry> co2Data = new ArrayList<>(); if (response.body() != null) { for (SaunaBitResponse.SaunaBit data : response.body()) { float x = convertTimeToSeconds(data.time); float y = data.co2; if (y != 0) { co2Data.add(new Entry(x, y)); } } // 排序与设置图表数据 co2Data.sort(Comparator.comparingFloat(Entry::getX)); setLineChartData(co2Data); } } @Override public void onFailure(@NonNull Call<List<SaunaBitResponse.SaunaBit>> call, @NonNull Throwable t) { t.printStackTrace(); } }); } // 辅助方法:将HH:mm:ss转换为当天的总秒数 private float convertTimeToSeconds(String timeStr) { try { String[] timeParts = timeStr.split(":"); int hours = Integer.parseInt(timeParts[0]); int minutes = Integer.parseInt(timeParts[1]); int seconds = Integer.parseInt(timeParts[2]); return hours * 3600 + minutes * 60 + seconds; } catch (Exception e) { e.printStackTrace(); return 0f; // 异常情况返回默认值 } }如果你使用Android 8.0+,也可以用
LocalTime简化转换:private float convertTimeToSeconds(String timeStr) { try { LocalTime localTime = LocalTime.parse(timeStr); return localTime.toSecondOfDay(); } catch (Exception e) { e.printStackTrace(); return 0f; } }
方案2:修改后端API返回数值类型(推荐,减少前端处理)
如果有权限修改后端代码,将Measurements类中的time字段改为数值类型(如当天的秒数,或时间戳):
- 更新后端实体类
@Entity @Table(name = "Measurement") public class Measurements { // ... 其他字段不变 private int timeInSeconds; // 替换原来的Time类型,存储当天的总秒数 // ... 对应的getter/setter } - 修改API返回逻辑
在查询数据时,将Time类型转换为秒数返回,这样Android端可以直接用long或float接收,无需额外转换。
内容的提问来源于stack exchange,提问作者Matej Hackl
相关产品推荐
相关产品推荐

