为何使用Dispatchers.IO仍运行在主线程?异常原因解析
问题原因分析
你遇到的问题核心是混淆了标准库的with函数与协程库的withContext函数,两者的作用完全不同:
with是Kotlin标准库的普通作用域函数,它仅用于在代码块中便捷访问某个对象的成员(通过this指代该对象),不会改变协程的调度器,也不会切换线程。你这里传入Dispatchers.IO给with,只是在代码块里把this指向Dispatchers.IO这个Dispatcher对象,但协程仍然在原来的主线程上运行,所以Looper.myLooper()会等于主线程的Looper,最终抛出异常。withContext是kotlinx.coroutines库提供的协程函数,它的作用是切换协程的上下文(包括指定Dispatcher),会挂起当前协程,在目标Dispatcher对应的线程上执行代码块,执行完成后再恢复原协程。这才是实现协程线程切换的正确方式。
修正后的代码
将with替换为withContext即可达到预期效果:
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycleScope.launchWhenCreated { withContext(Dispatchers.IO) { if (Looper.myLooper() == Looper.getMainLooper()) { throw Exception("we are on the main thread, though Dispatchers.IO is used") } // 此处代码将在IO线程执行,不会触发异常 } } } }
内容的提问来源于stack exchange,提问作者me.at.coding
相关产品推荐
相关产品推荐

