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

Android端Ktor二次启动报Parent job is Completed错误如何解决

问题根因

Android端使用Ktor 2.0.2时,首次启动正常、按返回键退出后二次启动崩溃,抛出Parent job is Completed错误,核心原因是二次启动时复用了内部协程作用域已经被终止的HttpClient实例。
你当前通过Hilt将HttpClient声明为@Singleton,正常情况下单例生命周期和应用进程绑定,出现这个异常通常由两个问题触发:

  • 代码中在Activity/Fragment/ViewModel等短生命周期组件的销毁回调(如onDestroy)里手动调用了单例HttpClient的close()方法。第一次按返回键退出页面时触发close,将HttpClient内部的父协程Job标记为完成状态;二次启动时Hilt不会重新创建单例实例,返回的是已经失效的Client,发起请求直接抛出异常。
  • Ktor 2.0.2版本的Android客户端引擎存在已知生命周期缺陷,应用退到后台触发系统资源回收时,会意外终止Client内部的协程父Job。
修复方案

1. 排查错误的close调用

全局单例HttpClient的生命周期和应用进程一致,不需要在页面退出、应用切后台等场景主动调用close()方法,检查代码删除所有在非应用全局生命周期位置调用单例HttpClientclose()的逻辑。

2. 升级Ktor版本修复引擎已知bug

Ktor 2.0.2的Android引擎生命周期问题在2.0.3及后续版本已经修复,直接升级Ktor版本即可,不需要修改现有业务逻辑,推荐升级到2.x分支的最新稳定版:

// 最低修复版本为2.0.3,可直接使用最新2.x稳定版
const val ktor_version = "2.3.12"

const val ktor_client_core = "io.ktor:ktor-client-core:$ktor_version"
const val ktor_serialization_json = "io.ktor:ktor-serialization-kotlinx-json:$ktor_version"
const val ktor_android = "io.ktor:ktor-client-android:$ktor_version"
const val ktor_negotiation = "io.ktor:ktor-client-content-negotiation:$ktor_version"
const val ktor_logging = "io.ktor:ktor-client-logging:$ktor_version"

3. 清理冗余依赖避免冲突

你当前引入的依赖存在冗余和版本兼容风险:

  • 同时引入了ktor-client-android、ktor-client-cio、ktor-client-okhttp三个客户端引擎,运行时仅会生效一个,多余引擎不仅增加包体积,还可能引发生命周期冲突,仅保留实际使用的ktor-client-android即可,删除另外两个引擎依赖。
  • ktor-client-serialization是Ktor 1.x版本的序列化组件,Ktor 2.x已经统一使用ktor-client-content-negotiation实现内容协商,删除这个旧依赖避免版本冲突。

4. 临时兼容方案(无法升级版本时使用)

如果暂时无法升级Ktor版本,可以在创建HttpClient时手动指定绑定IO调度器的独立SupervisorJob,避免内部协程作用域被外部逻辑意外终止:

@InstallIn(SingletonComponent::class)
@Module
object NetworkModule {

    private const val TIME_OUT = 60_000
    @Singleton
    @Provides
    fun provideKtor(): HttpClient = HttpClient(Android) {
        // 新增独立协程上下文配置,避免父Job被意外取消
        engine {
            dispatcher = Dispatchers.IO + SupervisorJob()
        }
        
        install(HttpCache)
        
        defaultRequest {
            contentType(ContentType.Application.Json)
            accept(ContentType.Application.Json)
        }

        install(ContentNegotiation) {
            json(json = Json {
                prettyPrint = true
                ignoreUnknownKeys = true
                isLenient = true
                encodeDefaults = false
            })
        }

        install(HttpTimeout) {
            connectTimeoutMillis = TIME_OUT.toLong()
            socketTimeoutMillis = TIME_OUT.toLong()
            requestTimeoutMillis = TIME_OUT.toLong()
        }

        install(ResponseObserver) {
            onResponse { response ->
                Log.d("HttpClientLogger - HTTP status", "${response.status.value}")
                Log.d("HttpClientLogger - Response:", response.toString())
            }
        }

        install(Logging) {
            logger = object : Logger {
                override fun log(message: String) {
                    Log.v("Logger Ktor =>", message)
                }

            }
            level = LogLevel.NONE
        }
    }
}
崩溃堆栈参考

stackTrace

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:01:02