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

Fragment中使用Coroutine导致导航跳转后新页面UI无法渲染问题

问题诱因排查及修复方案

核心诱因

  • ResponseBody的流只能消费一次
    ResponseBody的byteStream()是单次可读的流,你在前一个Fragment的协程里已经把整个流读完生成临时文件了,当你跳转到下一个Fragment如果复用同一个pdfResponse实例去加载PDF,流已经处于结束状态,读不到任何数据,自然不会渲染内容,表现为UI空白。
  • 协程取消不生效
    你用的InputStream.read()是JDK的阻塞IO方法,不响应协程的取消信号,就算前一个Fragment销毁、lifecycleScope触发了取消,这个阻塞读的操作依然会继续执行直到流读完,不会提前终止,也就意味着流还是会被前一个Fragment的协程消费完。
  • 异常被全吞排查难度高
    你协程的catch块、getTempPdfFile方法的catch块全是空实现,不管是协程取消异常、IO异常还是流读取异常都被你吃掉了,没有日志输出,你根本感知不到运行时的错误。

修复建议

  • 避免在跳转前消费ResponseBody
    如果下一个Fragment需要加载这个PDF,不要在前一个Fragment提前读流,要么把流消费逻辑放到下一个Fragment执行,要么前一个Fragment读完生成临时文件后,把文件路径传给下一个Fragment直接加载本地文件,不要重复读ResponseBody。
  • 让IO操作支持协程取消
    可以在每次循环读的时候加ensureActive()判断协程是否已经取消,协程销毁时会直接终止读操作:
while (true) {
    ensureActive()
    val read: Int = inputStream.read(fileReader)
    if (read == -1) {
        break
    }
    outputStream.write(fileReader, 0, read)
    fileSizeDownloaded += read.toLong()
}
  • 不要空吞异常
    至少在catch块里加日志打印,同时不要捕获协程取消异常,保证协程可以正常终止:
catch (e: Exception) {
    Log.e("PdfLoad", "加载PDF出错", e)
    if (e is CancellationException) throw e
}

内容的提问来源于stack exchange,提问作者AndroidDev123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:24:04