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)
}
1条答案
按热度按时间2ic8powd1#
关键是,您不必在等待suspend函数执行它可能正在使用其他线程执行的任何耗时任务时阻塞当前线程。然后,当它完成时,它可以将结果返回到原始线程上,也就是说,如果在单线程调度器的上下文中调用了suspend函数。
这是一种常见的情况。UI视图只能在主线程上使用,但我们不能阻止主线程等待某些东西,因为这会冻结整个UI,使其无法响应。这对用户来说将是一种可怕的体验,因为他们根本无法与设备交互,并且在等待时屏幕会冻结。因此,我们使用一个挂起函数来执行耗时的操作,这些操作必须不会阻塞主线程。
在底层,
getSomethingFromTheNetwork()
函数必须将其耗时的工作适当地委托给可接受阻塞的线程。如果它只是单纯地执行阻塞工作而没有适当地挂起,那么它就违反了约定,并且仍然会阻塞调用线程。这将破坏暂停功能的目的。