Lambda内部Coroutine launch不生效问题求助
问题原因与解决方案
你代码里launch启动的协程未执行,核心原因有两种可能:
1. 协程启动时,runBlocking作用域已结束
如果MessageParser的onStart回调是在**runBlocking代码块执行完毕后**才被触发的(比如MessageParser通过异步逻辑、其他线程延迟调用onStart),此时runBlocking已经退出,它管理的协程上下文被取消,新启动的协程会被立刻终止,自然不会执行任何代码。
2. 单线程调度器下协程未被调度(同步调用onStart场景)
如果MessageParser构造函数里同步调用了onStart,runBlocking默认使用单线程调度器,当前线程会先执行完onStart里的同步代码(打印On text、On text exit),随后直接走到runBlocking代码块末尾。虽然runBlocking会等待子协程完成,但如果程序此时直接退出(比如requestLooper.start没有阻塞逻辑),协程可能还没来得及被调度执行就被终止了。
对应解决方案
针对场景1(异步触发onStart)
用CompletableDeferred让runBlocking等待协程执行完成:
fun main(args: Array<String>) = runBlocking { val requestLooper = RequestLooper() val startSignal = CompletableDeferred<Unit>() val messageParser = MessageParser( onStart = { chatId -> println("On text") launch { try { println("Enter coroutine") requestLooper.start(chatId) } finally { startSignal.complete(Unit) } } println("On text exit") }, onStop = { chatId -> requestLooper.stop(chatId) } ) startSignal.await() // 阻塞等待协程执行完毕 }
针对场景2(同步调用onStart)
保存launch返回的Job,在runBlocking末尾调用join()等待协程完成:
fun main(args: Array<String>) = runBlocking { val requestLooper = RequestLooper() var startJob: Job? = null val messageParser = MessageParser( onStart = { chatId -> println("On text") startJob = launch { println("Enter coroutine") requestLooper.start(chatId) } println("On text exit") }, onStop = { chatId -> requestLooper.stop(chatId) } ) startJob?.join() // 等待协程执行完毕 }
内容的提问来源于stack exchange,提问作者EinTheFrog
相关产品推荐
相关产品推荐

