Okio源无法在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'
在Coroutine(即主线程中)在Coroutine(即Main线程中)进行以下日志,结果在位图中正确解码。感谢您的帮助,了解为什么源为何在Coroutine内部未正确阅读。
I am trying to generate a Bitmap from an Okio source using this implementation
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)
}
}
}
}
Thing is, the resulting bitmap is null
and I get the following logs
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'
Doing the same operation outside a coroutine (i.e. in the main thread) results in the Bitmap properly decoded. I appreciate your help finding out why the source is not correctly read inside the coroutine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
片段有一些问题:
cancel()
)。okio.source(file)
打开涉及可以阻止的文件I/O的文件。打开IO调度器上Coroutine内部的文件。使用
块中进行缓冲。通过调用使用{启动{}}
您要关闭文件,然后在启动的coroutine可以运行以读取文件之前。一起打开并缓冲文件源。使用
文件块在将Coroutine转移到主调度器之前完成。最终代码应该看起来像这样:
另外,考虑升级您的OKIO版本,该版本现在用Kotlin编写,并通过扩展功能工作:
There's a few things wrong with your snippet:
cancel()
somewhere).Okio.source(File)
opens the file which involves file I/O that can block. Open the file inside the coroutine on the IO dispatcher.use
block. By callinguse { launch { } }
you are closing the file before the launched coroutine can run to read the file. Open and buffer the file source together.use
block of the file to complete before transfering the coroutine to the main dispatcher.The final code should look something like this:
Also, consider upgrading your Okio version which is now written in Kotlin and works via extension functions: