You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin协程中读取Okio source报错流关闭致Bitmap解码失败

问题根因

use 资源关闭块的执行逻辑和协程异步调度逻辑冲突,导致流在解码前被提前关闭:

  • Kotlin 的 use 扩展函数是同步执行的,代码块内逻辑走完就会立刻自动调用资源的 close() 方法,不会感知块内启动的异步任务
  • CoroutineScope.launch 是非阻塞调用,启动协程后会立刻返回,不会等待协程内部代码执行完成
  • 原代码中,Okio.source(file).use 块在启动协程后就立刻执行完毕,自动关闭了底层文件流;等协程被调度到IO线程真正执行 BitmapFactory.decodeStream 读流时,流资源已经被释放,因此抛出 java.io.IOException: Stream Closed,解码返回null。

直接在主线程同步执行时,解码逻辑是在use块内部同步跑完的,流会等解码完成后才关闭,所以能正常生成Bitmap。

修复代码

将Okio资源的生命周期和协程对齐,把use块整体挪到协程内部,保证流在解码完成前不会被提前关闭:

val file = /* ... */
// 建议替换为页面绑定的生命周期协程Scope(如lifecycleScope),避免内存泄漏
CoroutineScope(Dispatchers.IO).launch {
    Okio.source(file).use { source ->
        Okio.buffer(source).use { bufferedSource ->
            val bitmap = BitmapFactory.decodeStream(bufferedSource.inputStream())
            withContext(Dispatchers.Main) {
                view.setImageBitmap(bitmap)
            }
        }
    }
}
补充说明
  • 无绑定关系的全局CoroutineScope会导致协程生命周期不受页面管控,页面销毁后协程仍在运行容易触发内存泄漏、View空指针问题,业务场景下优先使用和组件生命周期绑定的协程Scope
  • BitmapFactory.decodeStream 读流出错时默认不会抛出上层可捕获的异常,只会返回null,排查解码问题时可通过配置BitmapFactory.Options的debug日志开关获取更详细的底层错误信息

内容的提问来源于stack exchange,提问作者Nicolás Arias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:09:21