Android使用Volley请求JSON数据无法插入ArrayList问题求助
问题原因
核心是Volley网络请求为异步执行逻辑,你当前的代码执行顺序是:
- 初始化空ArrayList
- 创建网络请求、加入Volley请求队列
- 直接返回还未被填充的空列表
- 后续网络请求成功,在子线程完成后切回主线程执行回调里的list.add操作,此时createDataset方法早已执行完毕返回,你拿到的始终是初始的空列表。
另外你贴的代码里还有一个语法错误:val API_Image : String = item.getString("product_image").末尾多了一个多余的点,会导致编译失败。
解决方案
改用回调的方式获取请求完成后的列表,不要用同步返回的写法:
步骤1:定义数据加载回调接口
interface ItemPostLoadCallback { // 加载成功返回填充完成的列表 fun onLoadSuccess(list: List<ItemPost>) // 加载失败返回错误信息 fun onLoadFailed(errorMsg: String) }
步骤2:修改createDataset方法
去掉返回值,改为传入回调参数,请求完成后通过回调返回结果:
fun createDataset(callback: ItemPostLoadCallback) { val url = "http://api.karawcraftventure.com/item" val list = ArrayList<ItemPost>() val queue = Volley.newRequestQueue(activity) val jsonArrayRequest = JsonArrayRequest( Request.Method.GET, url, null, { response -> Toast.makeText(context, "API CALL SUCCESS", Toast.LENGTH_SHORT).show() try { for (i in 0 until response.length()) { val item : JSONObject = response.getJSONObject(i) // 已删除原代码末尾多余的点 val API_Image : String = item.getString("product_image") val API_ItemName : String = item.getString("product_name") val API_Price : String = item.getString("product_price") val API_Category : String = item.getString("product_category") list.add( ItemPost( API_Image, API_ItemName, API_Category, API_Price ) ) } // 数据填充完成,回调返回结果 callback.onLoadSuccess(list) } catch (e: JSONException) { e.printStackTrace() callback.onLoadFailed("数据解析失败:${e.message ?: "未知错误"}") } }, { error: VolleyError? -> val errorMsg = error?.message ?: "未知网络错误" Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show() callback.onLoadFailed(errorMsg) } ) queue.add(jsonArrayRequest) }
步骤3:调整调用逻辑
原有直接调用createDataset()获取返回值的逻辑作废,改为传入回调获取结果:
createDataset(object : ItemPostLoadCallback { override fun onLoadSuccess(list: List<ItemPost>) { // 此处可以拿到完整的列表,执行后续UI操作,例如刷新RecyclerView yourRecyclerAdapter.updateData(list) yourRecyclerAdapter.notifyDataSetChanged() } override fun onLoadFailed(errorMsg: String) { // 此处处理加载失败的逻辑,例如展示空状态、错误提示 } })
额外注意事项
- Volley的请求成功/失败回调默认运行在主线程,可以直接操作UI无需手动切线程
- 需在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 由于你使用的是http协议的接口,高版本Android默认禁止明文流量请求,需要在manifest的
application标签添加属性android:usesCleartextTraffic="true"才能正常请求。
内容的提问来源于stack exchange,提问作者Apprent1ce
相关产品推荐
相关产品推荐

