使用OkHttp将响应写入JSON文件时抛出'closed'异常的问题求助
使用OkHttp将响应写入JSON文件时抛出'closed'异常的问题求助
嘿,我看到你遇到的问题了,这个报错其实是OkHttp的一个常见坑——ResponseBody的string()方法只能被调用一次!
问题原因
当你第一次调用response.body()?.string()的时候,OkHttp会把响应体的流读取出来转换成字符串,同时会自动关闭这个流。等你第二次再调用它的时候,流已经处于关闭状态,自然就抛出了IllegalStateException: closed异常,这就是你代码里osw.write(response.body()?.string())行报错的原因。
解决方案
你只需要把响应内容先保存到一个变量里,之后再重复使用这个变量就可以了。另外建议用use块来自动管理流的关闭,避免资源泄漏。修改后的代码如下:
val request = Request.Builder().url(url).header("apikey", key).build() val client = OkHttpClient() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 建议添加失败处理逻辑,比如打印错误日志 e.printStackTrace() } override fun onResponse(call: Call, response: Response) { // 仅调用一次string(),将响应内容存入变量 val responseContent = response.body()?.string() ?: run { println("响应体为空") return } // 打印响应内容 println(responseContent) val date = LocalDate.now() // 使用use块自动关闭OutputStreamWriter,无需手动调用close() OutputStreamWriter(openFileOutput("$date.json", MODE_PRIVATE)).use { osw -> osw.write(responseContent) println("finished") } } })
额外提醒:OkHttp的回调是在子线程执行的,如果之后你需要更新UI,记得切换回主线程哦(比如用runOnUiThread或者Coroutine)。
备注:内容来源于stack exchange,提问作者Lukas
相关产品推荐
相关产品推荐

