在学习okhttp的时候,请求网络上一张图片并展示。写完代码后运行了一下,结果crash了。并且异常堆栈也无法直接看出具体怎么出现的问题。代码如下:
thread {
//同步方式
var clien: OkHttpClient = OkHttpClient.Builder().readTimeout(Duration.ofMillis(20000)).build()
var request: Request = Request.Builder()
.url("https://images.csdn.net/20150817/1.jpg")
.build()
val response = clien.newCall(request).execute()
var res = response.body?.string()
var stream = response.body?.byteStream()
var bitmap: Bitmap = BitmapFactory.decodeStream(stream)
runOnUiThread {
image.setImageBitmap(bitmap)
}
}
居然报了一个空指针异常,但是通过log或者打断点方式都验证了stream不为空。
这是什么情况呢?网上查了下decodeStream is null的报错,说是两次调用了decodeStream导致了decodeStream 返回null。这就很奇怪了,应该是之前的方法内部有调用decodeString。
此时注意到代码中有调用response.body?.string(), 它会加载整个response.body到内存中,在它内部可能有调用decodeStram()。
下面尝试把它注释掉再重新运行一下:
运行后成功加载除了图片,看来就是这一行代码导致的crash。
但是我看了response.body?.string()却没看到内部有调用deocdeStream的操作或其他可能引发问题的操作。这里记录一下,后面知道了再补充。
在另外一篇文章中看到,调用response.body?.string() 只可以使用一次,string()读取完内容后就会调用close()关闭,猜测这导致了输入流inputStream被关闭了,所以decodeStream()返回null。具体参考解决response.body().string()无法读取多次的问题_Mike_fei的博客-CSDN博客_response.body().string()