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

Volley请求回调中无法返回实体类列表问题求助

问题原因

你的代码报错核心原因是Volley网络请求是异步执行的:

  • 外层getChannels函数在调用requestQueue.add(stringRequest)后会立刻执行完毕,但网络响应的回调代码要等请求完成后才会触发。
  • 回调lambda里的return默认是试图返回lambda本身,而非外层的getChannels函数,因此会提示“return isn't allowed here”。
  • 更关键的是,异步操作的结果无法通过同步函数直接返回——函数执行结束时,请求结果还未生成。
解决方案

下面提供两种常用的处理方式:

方式一:使用回调接口(传统异步处理)

定义回调接口,将请求结果通过接口方法传递出去:

1. 定义回调接口

interface ChannelsCallback {
    fun onSuccess(channels: List<TblChannel>)
    fun onFailure(error: Exception)
}

2. 修改getChannels函数

fun getChannels(callback: ChannelsCallback) {
    val stringRequest = JsonObjectRequest(
        Request.Method.GET, "$baseUrl/api/json/channel_list.json",
        null,
        { response ->
            try {
                val gson = Gson()
                val token = TypeToken.getParameterized(ArrayList::class.java, TblChannel::class.java).type
                val channels1: JSONArray = response.getJSONArray("groups").getJSONObject(0).getJSONArray("channels")
                val channels = gson.fromJson<List<TblChannel>>(channels1.toString(), token)
                // 请求成功时回调结果
                callback.onSuccess(channels)
            } catch (e: Exception) {
                Log.e(tag, "DkPrintError on getChannels: $e")
                callback.onFailure(e)
            }
        },
        { error ->
            Log.e(tag, "DkPrintError on getChannels: $error")
            callback.onFailure(error)
        })

    requestQueue.add(stringRequest)
}

3. 调用示例

getChannels(object : ChannelsCallback {
    override fun onSuccess(channels: List<TblChannel>) {
        // 在这里处理拿到的频道列表
    }

    override fun onFailure(error: Exception) {
        // 处理请求失败的情况
    }
})

方式二:使用Kotlin协程(推荐,写法更简洁)

将异步请求包装成挂起函数,用协程实现“同步写法”处理异步逻辑:

修改getChannels为挂起函数

suspend fun getChannels(): List<TblChannel> {
    return suspendCoroutine { continuation ->
        val stringRequest = JsonObjectRequest(
            Request.Method.GET, "$baseUrl/api/json/channel_list.json",
            null,
            { response ->
                try {
                    val gson = Gson()
                    val token = TypeToken.getParameterized(ArrayList::class.java, TblChannel::class.java).type
                    val channels1: JSONArray = response.getJSONArray("groups").getJSONObject(0).getJSONArray("channels")
                    val channels = gson.fromJson<List<TblChannel>>(channels1.toString(), token)
                    continuation.resume(channels)
                } catch (e: Exception) {
                    Log.e(tag, "DkPrintError on getChannels: $e")
                    continuation.resumeWithException(e)
                }
            },
            { error ->
                Log.e(tag, "DkPrintError on getChannels: $error")
                continuation.resumeWithException(error)
            })

        requestQueue.add(stringRequest)
    }
}

调用示例(需在协程作用域内)

Android中通常使用viewModelScope、lifecycleScope等,测试时可用runBlocking:

viewModelScope.launch {
    try {
        val channels = getChannels()
        // 处理频道列表
    } catch (e: Exception) {
        // 处理请求失败
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:05:22