[英]Okio source cannot be read inside a Kotlin Coroutine
我正在尝试使用此实现从 Okio 源生成位图
val file = /* ... */
Okio.source(file).use {
CoroutineScope(Dispatchers.IO).launch {
Okio.buffer(source).use { bufferedSource ->
val bitmap = BitmapFactory.decodeStream(bufferedSource.inputStream())
withContext(Dispatchers.Main) {
view.setImageBitmap(bitmap)
}
}
}
}
事情是,生成的位图为null
,我得到以下日志
W/System.err: java.io.IOException: Stream Closed
W/System.err: at java.io.FileInputStream.read(FileInputStream.java:313)
W/System.err: at okio.InputStreamSource.read(Okio.kt:102)
W/System.err: at okio.RealBufferedSource$inputStream$1.read(RealBufferedSource.kt:438)
W/System.err: at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
W/System.err: at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:790)
W/System.err: at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:765)
W/System.err: at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:806)
W/System.err: at **************************************$1.invokeSuspend(ImageRenderer.kt:32)
W/System.err: at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
W/System.err: at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
W/System.err: at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
W/System.err: at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749)
W/System.err: at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
W/System.err: at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
D/skia: ---- read threw an exception
D/skia: --- Failed to create image decoder with message 'unimplemented'
在协程之外(即在主线程中)执行相同的操作会导致位图正确解码。 感谢您帮助找出为什么在协程中未正确读取源代码。
您的代码段有一些问题:
cancel()
)。Okio.source(File)
打开涉及可能阻塞的文件 I/O 的文件。 在 IO 调度程序上打开协程内的文件。use
块。 通过调用use { launch { } }
您正在关闭文件,然后启动的协程可以运行以读取文件。 一起打开和缓冲文件源。use
块完成。最终代码应如下所示:
val file = /* ... */
scope.launch(Dispatchers.IO) {
val bitmap = Okio.buffer(Okio.source(file)).use { bufferedSource ->
BitmapFactory.decodeStream(bufferedSource.inputStream())
}
withContext(Dispatchers.Main) {
view.setImageBitmap(bitmap)
}
}
此外,请考虑升级您的 Okio 版本,该版本现在用 Kotlin 编写并通过扩展函数工作:
val file = /* ... */
scope.launch(Dispatchers.IO) {
val bitmap = file.source().buffer().use { bufferedSource ->
BitmapFactory.decodeStream(bufferedSource.inputStream())
}
withContext(Dispatchers.Main) {
view.setImageBitmap(bitmap)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.