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

如何等待Android Volley请求响应 解决异步返回数组为空问题

问题根因

Volley的网络请求默认在异步子线程执行,你当前的写法会在将请求加入队列后立刻返回chartDataList,此时请求还未完成、回调逻辑还未触发,自然拿到的是空数组。Android禁止在主线程阻塞等待网络请求返回,否则会触发ANR异常,因此不能直接用同步阻塞的方式等待结果,推荐用接口回调的方式获取请求完成后的数据。

另外你原有代码存在隐藏bug:仅在循环外创建了一次ChartData实例,循环内反复修改同一个对象的属性,最终列表里所有元素都会是最后一条数据的内容,后续方案中已经修复该问题。


解决方案1:Java接口回调实现(通用方案)

步骤1:自定义回调接口

public interface VolleyResponseCallback {
    // 请求成功返回填充完成的数组
    void onSuccess(List<ChartData> dataList);
    // 请求/解析失败返回错误信息
    void onError(String errorMsg);
}

步骤2:修改原有请求方法

去掉方法返回值,改为传入回调参数,处理完逻辑后通过回调返回结果:

public void getVolleyResponse(VolleyResponseCallback callback) {
        requestQueue = Volley.newRequestQueue(getApplicationContext());
        JsonObjectRequest req = new JsonObjectRequest(
                Request.Method.GET,
                urlCreator(getCoinName()),
                null,
                response -> {
                    try {
                        JSONArray arr = response.getJSONArray("prices");
                        List<ChartData> chartDataList = new ArrayList<>();
                        for (int i = 0; i < arr.length(); i++) {
                            JSONArray jsonArray = arr.getJSONArray(i);
                            // 每次循环创建新的ChartData实例,修复对象复用bug
                            ChartData chartData = new ChartData();
                            chartData.setTimeStamp(timeStampConverter(jsonArray.getString(0)));
                            chartData.setCost(jsonArray.getDouble(1));
                            chartDataList.add(chartData);
                        }
                        // 回调返回成功结果
                        callback.onSuccess(chartDataList);
                    } catch (JSONException e) {
                        e.printStackTrace();
                        callback.onError("数据解析失败:" + e.getMessage());
                    }
                },
                error -> {
                    String errorTip = "请求失败:" + (error.getMessage() == null ? "未知错误" : error.getMessage());
                    Toast.makeText(getApplicationContext(), errorTip, Toast.LENGTH_LONG).show();
                    callback.onError(errorTip);
                });
        requestQueue.add(req);
}

步骤3:调用方法获取数据

getVolleyResponse(new VolleyResponseCallback() {
    @Override
    public void onSuccess(List<ChartData> dataList) {
        // 此处拿到填充完成的数组,可直接更新UI或执行后续逻辑
        // 回调默认运行在主线程,无需额外切线程
    }

    @Override
    public void onError(String errorMsg) {
        // 自定义错误处理逻辑
    }
});

解决方案2:Kotlin协程实现(Kotlin项目可选)

如果项目使用Kotlin开发,可以通过suspendCoroutine将回调转为挂起函数,写法更简洁:

suspend fun getVolleyResponse(): Result<List<ChartData>> = suspendCoroutine { continuation ->
    val requestQueue = Volley.newRequestQueue(applicationContext)
    val req = JsonObjectRequest(
        Request.Method.GET,
        urlCreator(getCoinName()),
        null,
        { response ->
            try {
                val arr = response.getJSONArray("prices")
                val dataList = mutableListOf<ChartData>()
                for (i in 0 until arr.length()) {
                    val jsonArray = arr.getJSONArray(i)
                    val chartData = ChartData().apply {
                        timeStamp = timeStampConverter(jsonArray.getString(0))
                        cost = jsonArray.getDouble(1)
                    }
                    dataList.add(chartData)
                }
                continuation.resume(Result.success(dataList))
            } catch (e: JSONException) {
                e.printStackTrace()
                continuation.resume(Result.failure(e))
            }
        },
        { error ->
            Toast.makeText(applicationContext, "请求失败", Toast.LENGTH_LONG).show()
            continuation.resume(Result.failure(error))
        }
    )
    requestQueue.add(req)
}

调用时直接在协程作用域中获取结果即可。


注意事项
  • 不要使用CountDownLatch等工具在主线程阻塞等待异步请求返回,会直接触发ANR异常
  • 回调方法默认运行在主线程,可以直接执行UI更新操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:36:03