android 为什么协程在挂起时释放线程?

ni65a41a  于 2023-09-29  发布在  Android
关注(0)|答案(1)|浏览(151)

在关于协程的文档中,写到“在挂起点(例如,对网络的请求),协程挂起它的执行并在等待响应时释放线程”
我的问题是-为什么在请求网络时会释放流?等待响应也是线程上应该执行的操作。为什么我需要释放线程?

2ic8powd

2ic8powd1#

关键是,您不必在等待suspend函数执行它可能正在使用其他线程执行的任何耗时任务时阻塞当前线程。然后,当它完成时,它可以将结果返回到原始线程上,也就是说,如果在单线程调度器的上下文中调用了suspend函数。
这是一种常见的情况。UI视图只能在主线程上使用,但我们不能阻止主线程等待某些东西,因为这会冻结整个UI,使其无法响应。这对用户来说将是一种可怕的体验,因为他们根本无法与设备交互,并且在等待时屏幕会冻结。因此,我们使用一个挂起函数来执行耗时的操作,这些操作必须不会阻塞主线程。

lifecycleScope.launch {
    // The lifecycle scope uses the single-threaded Dispatchers.Main.

    showProgressIndicator() // A regular, non-blocking function that works with the UI

    val result = getSomethingFromTheNetwork() // A suspend function call. The main thread 
                                              // is now released so we aren't blocking 
                                              // it while we wait for the time-consuming
                                              // network fetch. The main thread will
                                              // continue to be used by other code
                                              // and be free to show animation and
                                              // accept user input.

    // The suspend function returns a value, and we have assigned it to the result 
    // variable above after resuming on the main thread again.

    hideProgressIndicator() // We can safely work with UI on the main thread.
    updateUI(result)
}

在底层,getSomethingFromTheNetwork()函数必须将其耗时的工作适当地委托给可接受阻塞的线程。如果它只是单纯地执行阻塞工作而没有适当地挂起,那么它就违反了约定,并且仍然会阻塞调用线程。这将破坏暂停功能的目的。

相关问题