You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发中Volley异步请求返回ArrayList为空问题排查

问题根因

Volley发起的网络请求是异步非阻塞的:当你调用add(jsonObjectRequest)把请求加入队列后,当前线程不会暂停等待网络请求完成、onResponse回调执行,而是会立刻继续往下执行return u1语句。
此时网络请求还在后台排队/传输,onResponse根本没有触发,你定义的静态集合u1里还没有被添加任何数据,所以调用方法后立刻读取集合size,得到的结果必然是0。
另外你当前代码还有两个隐藏问题:

  • 用静态全局集合u1存储单次请求结果,多次调用方法会导致历史数据残留,出现列表重复、数据错乱
  • 方法内新建了RequestQueue实例但没有使用,实际往MainActivity的静态队列加请求,容易出现队列空指针、重复创建队列浪费资源的问题
改造方案

异步网络请求的结果永远无法通过方法return直接返回,必须通过回调接口在请求完成时把结果传递出去,具体改造步骤如下:

  1. 定义请求结果回调接口,用来接收成功/失败的回调通知
public interface UserLoadCallback {
    void onSuccess(ArrayList<User> userList);
    void onLoadFailed(Exception error);
}
  1. 重构getUserPicture方法,移除全局静态集合,增加回调参数,在请求成功/失败时触发对应回调
public class Utils {
    public static void getUserPicture(String uid, Activity activity, UserLoadCallback callback) {
        // 初始化全局请求队列,避免重复创建
        if (MainActivity.requestQueue == null) {
            MainActivity.requestQueue = Volley.newRequestQueue(activity.getApplicationContext());
        }
        JSONObject requestParams = new JSONObject();
        String requestUrl = "https://ewserver.helpme/helpme.php";
        try {
            requestParams.put("uid", uid);
        } catch (JSONException e) {
            callback.onLoadFailed(e);
            return;
        }
        JsonObjectRequest profileRequest = new JsonObjectRequest(
                Request.Method.POST,
                requestUrl,
                requestParams,
                response -> {
                    ArrayList<User> resultList = new ArrayList<>();
                    try {
                        String pictureUrl = response.getString("picture");
                        resultList.add(new User(uid, pictureUrl));
                        callback.onSuccess(resultList);
                    } catch (JSONException e) {
                        callback.onLoadFailed(e);
                    }
                },
                error -> callback.onLoadFailed(error)
        );
        MainActivity.requestQueue.add(profileRequest);
    }
}
  1. 修改调用逻辑,在回调方法中处理拿到的用户列表数据,不要在方法调用后立刻读取结果
getUserPicture(uid, activity, new UserLoadCallback() {
    @Override
    public void onSuccess(ArrayList<User> userList) {
        // 此处网络请求已完成,数据解析成功,可以正常使用列表
        Log.d("main_activity_usersize", String.valueOf(userList.size()));
        // 如需更新UI,注意要在主线程执行
    }

    @Override
    public void onLoadFailed(Exception error) {
        // 在此处处理网络错误、解析错误逻辑
        error.printStackTrace();
    }
});
注意事项
  • Android禁止在主线程执行同步网络请求,否则会触发ANR崩溃,不要尝试用阻塞线程的方式等待异步请求返回
  • 单次请求的结果存在方法局部变量中即可,不要用静态全局集合存储,避免多请求数据污染
  • Volley的RequestQueue建议做成应用级单例,不要每次请求都新建实例,减少内存开销

内容的提问来源于stack exchange,提问作者Elly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:06:22