首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在Kotlin Coroutine中读取Okio源

无法在Kotlin Coroutine中读取Okio源
EN

Stack Overflow用户
提问于 2022-07-06 20:10:12
回答 1查看 204关注 0票数 0

我正在尝试使用这个实现从Okio源生成一个位图。

代码语言:javascript
复制
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,我得到以下日志

代码语言:javascript
复制
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'

在协同线之外执行相同的操作(即在主线程中)将导致位图被正确解码。我很感激你的帮助,找出了为什么在协同线中没有正确地读取源。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-06 20:43:31

你的片段有几处不对劲:

  1. 您正在创建一个与某物的生命周期无关的范围(活动、片段、视图等等)。永远不要任意地创建一个作用域,并且总是将其启动到一个绑定到其他生命周期的范围中(例如,调用cancel()cancel()正在打开调用线程(主线程)上的文件)。Okio.source(File)打开涉及文件I/O的文件,该文件可以阻塞。打开IO dispatcher.
  2. You上的coroutine中的文件,use块正在缓冲。通过调用use { launch { } },在已启动的协同线能够运行以读取文件之前,您将关闭该文件。打开和缓冲文件源together.
  3. You在等待协同线在主线程上运行时保持缓冲源的活动。允许文件的use块在将协同线传输到主调度程序.

之前完成。

最后的代码应该如下所示:

代码语言:javascript
复制
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编写的,并通过扩展函数工作:

代码语言:javascript
复制
val file = /* ... */
    
scope.launch(Dispatchers.IO) {
  val bitmap = file.source().buffer().use { bufferedSource ->
    BitmapFactory.decodeStream(bufferedSource.inputStream())
  }

  withContext(Dispatchers.Main) {
    view.setImageBitmap(bitmap)
  }  
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72889332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档