Android Volley出现JSONException:JSONObject无法转为JSONArray求助
问题分析与修复方案
问题根源
从报错信息和API返回的JSON结构可以明确:
- API返回的JSON中,
files是一个JSONObject,而非你代码中期望的JSONArray,直接调用getJSONArray("files")必然触发类型转换异常 - 真正的文件列表数据嵌套在
files对象里的data字段中,这才是需要解析的JSONArray - 额外冗余操作:代码中重复创建了
Volley RequestQueue,完全可以复用同一个队列
API返回的核心JSON结构简化后如下:
{ "files": { "data": [/* 文件对象数组 */], "status": "OK" } }
修复代码
修改JSON解析逻辑,同时优化RequestQueue的创建:
import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.widget.SimpleAdapter; import java.util.ArrayList; import java.util.HashMap; public class MainActivity extends AppCompatActivity { Button btn_Submit; EditText et_dataInput; ListView lv_files; String file_name; String file_category; String file_keyword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_Submit = findViewById(R.id.btn_Submit); et_dataInput = findViewById(R.id.et_dataInput); lv_files = findViewById(R.id.lv_files); btn_Submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 只创建一次RequestQueue RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this); String url = "http://ws2.samdel.net/mongodb_api.php?s=" + et_dataInput.getText().toString(); StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { ArrayList<HashMap<String, String>> list = new ArrayList<>(); try { JSONObject jsonObject = new JSONObject(response); // 先获取files对应的JSONObject JSONObject filesObj = jsonObject.getJSONObject("files"); // 再从filesObj中取出真正的文件列表数组data JSONArray result = filesObj.getJSONArray("data"); for (int i = 0; i < result.length(); i++) { JSONObject jo = result.getJSONObject(i); file_name = jo.getString("files_name"); file_category = jo.getString("files_category"); file_keyword = jo.getString("files_keyword"); HashMap<String, String> data = new HashMap<>(); data.put("files_name", file_name); data.put("files_category", file_category); data.put("files_keyword", file_keyword); list.add(data); } } catch (JSONException e) { e.printStackTrace(); } // 替换为SimpleAdapter,避免直接显示HashMap对象地址 SimpleAdapter simpleAdapter = new SimpleAdapter( MainActivity.this, list, android.R.layout.simple_list_item_2, new String[]{"files_name", "files_category"}, new int[]{android.R.id.text1, android.R.id.text2} ); lv_files.setAdapter(simpleAdapter); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.i("My error", "Error Occurred" + error); } }); requestQueue.add(stringRequest); } }); } }
额外说明
原代码使用ArrayAdapter<HashMap<String,String>>会导致ListView显示HashMap的对象地址而非实际内容,因此替换为SimpleAdapter来正确展示文件信息,你也可以根据需求自定义ListView的Item布局和Adapter类。
内容的提问来源于stack exchange,提问作者Sepherys
相关产品推荐
相关产品推荐

