Kotlin Android使用Volley获取网络JSON返回空对象如何解决?
问题排查及解决方案
核心问题
- Volley的网络请求是异步执行的,你在初始化
MyRequest实例后立刻打印r.json,此时后台网络请求还未完成,取到的只是初始化的空JsonObject实例。 - 请求成功回调逻辑存在疏漏:
{ response -> json }只是无意义返回了空json变量,并没有把请求返回的response赋值给类成员json,就算请求完成也不会更新json的值。 - 多余调用
queue.start():Volley的newRequestQueue返回的请求队列已经默认启动,调用add()方法后会自动调度执行请求,不需要手动调用start()。
修复方案
推荐使用回调方式处理异步请求结果,修改后代码如下:
MyRequest类修改
class MyRequest( private val context: Context, private val url: String, // 定义回调参数:请求成功返回json,失败返回错误信息 private val onResult: (resultJson: JsonObject?, errorMsg: String?) -> Unit ) { init { val queue = Volley.newRequestQueue(context) val request = JsonObjectRequest( Request.Method.GET, url, null, { response -> // 请求成功时把结果通过回调传出 onResult(response, null) }, { error -> // 请求失败时把错误信息通过回调传出 onResult(null, error.message ?: "未知请求错误") } ) queue.add(request) } }
Database类test方法修改
val url: String = "http://...." fun test(){ MyRequest(context, url) { json, error -> // 先处理错误场景 error?.let { println("请求出错:$it") return@MyRequest } // 请求成功,这里才能拿到正确的json结果 json?.let { resultJson -> println(resultJson) // 所有后续json处理逻辑都要写在这个回调范围内 } } }
额外注意事项
- Android 9及以上系统默认禁止明文HTTP请求,如果你请求的地址是http开头,需要在
AndroidManifest.xml的application标签中添加android:usesCleartextTraffic="true"配置。 - 不要忘记在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者Smooki
相关产品推荐
相关产品推荐

