我正在尝试使用这个实现从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'在协同线之外执行相同的操作(即在主线程中)将导致位图被正确解码。我很感激你的帮助,找出了为什么在协同线中没有正确地读取源。
发布于 2022-07-06 20:43:31
你的片段有几处不对劲:
cancel(),cancel()正在打开调用线程(主线程)上的文件)。Okio.source(File)打开涉及文件I/O的文件,该文件可以阻塞。打开IO dispatcher.use块正在缓冲。通过调用use { launch { } },在已启动的协同线能够运行以读取文件之前,您将关闭该文件。打开和缓冲文件源together.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)
}
}https://stackoverflow.com/questions/72889332
复制相似问题