Android Studio循环存储JSON数据到数组崩溃,求解决方法
问题分析与解决方案
首先看你的错误日志:java.lang.ArrayIndexOutOfBoundsException: length=0; index=0,这说明你在访问一个未初始化的数组。你的代码里犯了两个关键错误:
1. 数组声明与初始化错误
- 你把
year错误声明成了二维数组:String[] year[];,但实际上只需要一维数组来存储每个条目里的年份值 - 所有数组(
year、month、day等)都仅做了声明,没有分配内存空间(也就是没初始化长度)。当你在for循环里尝试year[i] = ...时,数组的长度还是0,自然会抛出越界异常。
2. 原Toast只显示最后一行的原因
之前用单个变量存储数据时,每次循环都会覆盖之前的值,所以最后Toast只会显示最后一条数据。你改用数组的思路是对的,但初始化步骤没做好,导致了崩溃。
解决方案:推荐使用ArrayList(更灵活)
因为JSON返回的user_data条目数量是动态的,用ArrayList比固定长度的数组更合适,不需要提前知道长度。下面是修改后的代码:
步骤1:替换数组声明为ArrayList
把原来的数组声明替换成:
// 替换原来的数组声明,用动态列表存储数据 ArrayList<String> yearList = new ArrayList<>(); ArrayList<String> monthList = new ArrayList<>(); ArrayList<String> dayList = new ArrayList<>(); ArrayList<String> startTimeList = new ArrayList<>(); ArrayList<String> endTimeList = new ArrayList<>(); ArrayList<String> hoursList = new ArrayList<>();
步骤2:修改onPostExecute方法
在解析JSON时,把数据添加到ArrayList中,之后就可以遍历所有数据了:
@Override protected void onPostExecute(String result) { try { JSONObject root = new JSONObject(result); JSONArray user_data = root.getJSONArray("user_data"); // 先清空列表,避免重复添加数据 yearList.clear(); monthList.clear(); dayList.clear(); startTimeList.clear(); endTimeList.clear(); hoursList.clear(); for (int i = 0; i < user_data.length(); i++) { JSONObject jsonObject = user_data.getJSONObject(i); // 将每条数据添加到对应列表 yearList.add(jsonObject.getString("year")); monthList.add(jsonObject.getString("month")); dayList.add(jsonObject.getString("day")); startTimeList.add(jsonObject.getString("StartTime")); endTimeList.add(jsonObject.getString("Endtime")); hoursList.add(jsonObject.getString("Hours")); } // 测试:逐个拼接并显示所有数据 StringBuilder sb = new StringBuilder(); for (int i = 0; i < yearList.size(); i++) { sb.append("第").append(i+1).append("条数据:\n") .append("年份:").append(yearList.get(i)).append("\n") .append("月份:").append(monthList.get(i)).append("\n") .append("日期:").append(dayList.get(i)).append("\n") .append("开始时间:").append(startTimeList.get(i)).append("\n") .append("结束时间:").append(endTimeList.get(i)).append("\n") .append("时长:").append(hoursList.get(i)).append("\n\n"); } Toast.makeText(MainActivity.this, sb.toString(), Toast.LENGTH_LONG).show(); } catch (JSONException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "JSON解析错误:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } }
如果你坚持用数组(不推荐)
如果一定要用数组,需要在拿到user_data的长度后再初始化数组:
// 先把year的声明改成一维数组 String[] year; String[] month; String[] day; String[] StartTime; String[] Endtime; String[] Hours; // 修改onPostExecute方法 @Override protected void onPostExecute(String result) { try { JSONObject root = new JSONObject(result); JSONArray user_data = root.getJSONArray("user_data"); int dataCount = user_data.length(); // 根据数据长度初始化数组 year = new String[dataCount]; month = new String[dataCount]; day = new String[dataCount]; StartTime = new String[dataCount]; Endtime = new String[dataCount]; Hours = new String[dataCount]; for (int i = 0; i < dataCount; i++) { JSONObject jsonObject = user_data.getJSONObject(i); year[i] = jsonObject.getString("year"); month[i] = jsonObject.getString("month"); day[i] = jsonObject.getString("day"); StartTime[i] = jsonObject.getString("StartTime"); Endtime[i] = jsonObject.getString("Endtime"); Hours[i] = jsonObject.getString("Hours"); } // 测试打印第一条数据 Toast.makeText(MainActivity.this, "第一条数据年份:" + year[0], Toast.LENGTH_LONG).show(); // 遍历所有数据并打印到日志 for (int i = 0; i < dataCount; i++) { Log.d("UserData", "第" + (i+1) + "条:" + year[i] + "-" + month[i] + "-" + day[i]); } } catch (JSONException e) { e.printStackTrace(); } }
额外注意事项
- 你的PHP接口地址用了
http://localhost,在模拟器里访问本地电脑的PHP服务,需要把localhost换成电脑的局域网IP(比如http://192.168.x.x/sample/FETCH/fetch.php),否则模拟器会把localhost当成自己,访问不到电脑上的服务。 - 记得在AndroidManifest.xml里添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者selva surya
相关产品推荐
相关产品推荐

