Kotlin中runBlocking未生效求助:getGroupSummaries执行顺序异常
问题:runBlocking未正常阻塞导致后续代码提前执行
场景说明
我需要在后续代码执行前,确保suspend fun getGroupSummaries完全执行完毕,但当前实现出现异常:
- 打印
groupInformationList大小的日志,反而先于getGroupSummaries内部日志输出 - 外部日志显示集合大小为0,但函数内部日志显示大小为1
另外,制作最小复现示例时,移除循环后运行正常。
相关代码
函数声明
suspend fun getGroupSummaries(groupInfo: GroupInformation, adminUserInfo: UserInformation){ // 内部逻辑,会修改groupInformationList }
当前调用代码
runBlocking { val getGroupSummariesJob = viewModelScope.launch { getGroupSummaries(groupInformation, userInformation) } getGroupSummariesJob.join() } Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)
问题原因
viewModelScope默认使用Dispatchers.Main调度器,而runBlocking会阻塞当前线程(通常是主线程)。主线程被阻塞后,viewModelScope.launch启动的协程会被卡在主线程的任务队列里,根本没机会执行——join()只是等待Job的状态,但协程本身没运行,所以后续代码会提前执行,导致日志顺序颠倒、集合数据未更新。
解决建议
方案1:直接在runBlocking作用域内调用挂起函数
runBlocking本身就是协程作用域,直接调用挂起函数会自动等待其完成,无需额外启动Job:
runBlocking { getGroupSummaries(groupInformation, userInformation) } Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)
方案2:给viewModelScope.launch指定非主线程调度器
让协程在后台线程执行,避免被runBlocking阻塞的主线程影响:
runBlocking { val getGroupSummariesJob = viewModelScope.launch(Dispatchers.IO) { getGroupSummaries(groupInformation, userInformation) } getGroupSummariesJob.join() } Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)
方案3:避免用runBlocking阻塞主线程(推荐)
如果是在ViewModel中编写逻辑,直接用viewModelScope启动协程,在挂起函数执行完成后再处理后续逻辑:
viewModelScope.launch { getGroupSummaries(groupInformation, userInformation) Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size) }
内容的提问来源于stack exchange,提问作者scrayne
相关产品推荐
相关产品推荐

