Android中Volley JsonArrayRequest请求后私有列表mPlatList未更新
问题分析与修复方案
问题根源
- 异步请求时序错误:Volley的网络请求是异步执行的,PlatBank构造函数执行完毕时,请求还在后台运行,
mPlatList此时并未被填充。 - 多余的实例创建:
getAllPlatsStrings方法里重新new了一个PlatBank对象,这个新实例的请求刚发起,回调还未触发,所以getPlatList()必然为空——完全没必要新建实例,直接用当前对象的mPlatList即可。 - 数组操作潜在bug:初始化的
String[] mPlatListtoString = {}是长度为0的空数组,直接通过索引赋值会触发数组越界异常,只是当前循环未执行所以没暴露问题。
修复步骤
1. 给异步请求添加回调接口
网络请求是异步的,无法同步获取结果,必须通过回调通知数据加载完成,确保后续操作在数据准备好之后执行。
2. 重构getAllPlatsStrings逻辑
- 删除新建PlatBank的代码,直接使用当前实例的
mPlatList - 改用
ArrayList<String>先存储数据,再转成数组,避免数组越界问题
修正后的完整代码
public class PlatBank{ private List<Plat> mPlatList = new ArrayList<>(); private String mRetour = ""; // 定义数据加载完成的回调接口 public interface OnPlatsLoadedListener { void onPlatsLoaded(List<Plat> platList); void onLoadFailed(String errorMsg); } public PlatBank() { // 保留空构造,将请求逻辑抽为独立方法 } // 抽离请求方法,传入回调通知结果 public void loadPlats(OnPlatsLoadedListener listener) { String url = "xxx"; // 替换为你的实际接口地址 // 用Volley默认方式初始化RequestQueue,更规范 RequestQueue requestQueue = Volley.newRequestQueue(YourApplication.getContext()); JsonArrayRequest mJsonQuery = new JsonArrayRequest(url, response -> { mRetour = response.toString(); mPlatList.clear(); // 避免重复加载数据 for (int i = 0; i < response.length(); i++) { try { Plat mTempPlat = new Plat("id", (String) response.get(i)); mPlatList.add(mTempPlat); } catch (JSONException e) { e.printStackTrace(); listener.onLoadFailed("数据解析失败"); return; } } // 数据加载完成,通过回调通知外部 listener.onPlatsLoaded(mPlatList); }, error -> { mRetour = "KO"; listener.onLoadFailed("网络请求失败"); }); requestQueue.add(mJsonQuery); } public List<Plat> getPlatList(){ return mPlatList; } public String[] getAllPlatsStrings() { List<String> platStringList = new ArrayList<>(); for (Plat plat : mPlatList) { platStringList.add(plat.toString()); } // 转换为String数组返回 return platStringList.toArray(new String[0]); } }
使用示例
在Activity或Fragment中调用:
PlatBank platBank = new PlatBank(); platBank.loadPlats(new PlatBank.OnPlatsLoadedListener() { @Override public void onPlatsLoaded(List<Plat> platList) { // 仅在回调中,数据才是准备完成的 String[] platStrings = platBank.getAllPlatsStrings(); // 这里执行后续操作,比如更新UI } @Override public void onLoadFailed(String errorMsg) { // 处理加载失败的情况,比如弹出提示 } });
内容的提问来源于stack exchange,提问作者Cyril
相关产品推荐
相关产品推荐

