Android用Retrofit调用Jamendo API获取瑜伽音乐报错排查
解决Jamendo API获取瑜伽音乐时的JSONException错误
问题背景
开发Android应用时,通过Jamendo API的track端点获取瑜伽音乐,计划在带适配器的MusicListScreen中展示数据。已创建对应API返回JSON结构的YogaTracks类,但调用接口时抛出JSONException错误。
JSON响应示例
{"headers":{"status":"success","code":0,"error_message":"","warnings":"","results_count":2},"results":[{"id":"1532771","name":"Let Me Hear You I",...}]}
相关代码
MusicListScreen类代码
package com.minhhoang.yolo_yoga; // 省略其余代码 }
API接口代码
package JamendoAPI; // 省略其余代码 }
YogaTracks类代码
package JamendoAPI; // 省略其余代码 }
错误日志
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.RuntimeException: org.json.JSONException: Not a primitive array: class retrofit2.Response...
解决方案
根据错误信息,核心问题是将Retrofit的Response对象直接当作JSON数组解析,或未正确匹配API返回的JSON层级结构,以下是修复步骤:
1. 匹配JSON层级创建外层响应类
API返回的JSON最外层是包含headers和results的对象,而非数组。需创建外层响应类包裹YogaTracks:
public class JamendoResponse { public Headers headers; public List<YogaTracks> results; public static class Headers { public String status; public int code; public String error_message; public String warnings; public int results_count; } }
2. 修正Retrofit接口定义
确保接口返回类型为外层响应类,而非直接返回YogaTracks数组:
@GET("track") Call<JamendoResponse> getYogaTracks(@Query("your_param") String paramValue);
3. 正确处理响应解析
调用接口时,从Response中取出外层对象,再获取results列表:
apiService.getYogaTracks("yoga").enqueue(new Callback<JamendoResponse>() { @Override public void onResponse(Call<JamendoResponse> call, Response<JamendoResponse> response) { if (response.isSuccessful() && response.body() != null) { List<YogaTracks> yogaTracks = response.body().results; // 将列表传给MusicListScreen的适配器 } } @Override public void onFailure(Call<JamendoResponse> call, Throwable t) { // 处理请求失败逻辑 } });
4. 手动解析的修正(若未用Retrofit自动解析)
如果是手动解析JSON,不要直接将Response对象转为JSONArray,需先解析外层对象:
// 错误写法:直接将Response转为JSONArray // JSONArray jsonArray = new JSONArray(response); // 正确写法 String responseBody = response.body().string(); JSONObject rootObj = new JSONObject(responseBody); JSONArray resultsArray = rootObj.getJSONArray("results"); // 遍历数组解析每个YogaTracks List<YogaTracks> tracks = new ArrayList<>(); for (int i = 0; i < resultsArray.length(); i++) { JSONObject trackObj = resultsArray.getJSONObject(i); YogaTracks track = new YogaTracks(); track.setId(trackObj.getString("id")); track.setName(trackObj.getString("name")); // 赋值其他字段 tracks.add(track); }
内容的提问来源于stack exchange,提问作者Cyclone
相关产品推荐
相关产品推荐

