Bit*_*EVS 8 android kotlin kotlin-coroutines
GlobalScope 和 MainScope 有什么区别?
//Accessing data from Room
GlobalScope.launch {
v.tvStoreName.text = pfViewModel.getStoreName()
pageDetails.pageNumber = currentPage
pageDetails.pageSize = pageSize
pfViewModel.getTransactions(pageDetails, toolbarBuilder?.getDate()!!)
}
Run Code Online (Sandbox Code Playgroud)
GlobalScope 有时会犯一个很难重现的错误。
致命异常:android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。
MainScope().launch {
var storeName = ""
withContext(Dispatchers.Default) {
storeName = pfViewModel.getStoreName()
}
v.tvStoreName.text = storeName
}
Run Code Online (Sandbox Code Playgroud)
Jof*_*rey 16
GlobalScope 和 MainScope 有什么区别?
MainScopeCoroutineScope默认情况下使用调度程序Dispatchers.Main,它绑定到主 UI 线程。
是在其协程上下文中没有调度程序的GlobalScope。CoroutineScope这意味着在此范围内启动的协程将使用Dispatchers.Default调度程序,该调度程序由线程池支持(大小根据您拥有的 CPU 核心数量而定)。
GlobalScope在其上下文中也没有,这Job意味着结构化并发不适用。其中启动的协程永远不会自动取消,因此需要手动控制。这就是为什么通常不鼓励使用它,除非您有非常具体的需求。
只有创建视图层次结构的原始线程才能触摸其视图。
当您尝试从主线程外部修改视图时,就会发生此错误,如果您从主线程中启动的协程执行此操作,就会发生这种情况GlobalScope(因为它由单独的线程池支持)。
在第二个代码片段中,您使用的是withContext(Dispatchers.Default),它仅使这部分代码在该线程池上运行,但其余部分在 UI 线程上运行。这就是为什么 UI 更新可以正常进行的原因。
请注意,Room 已经使用带有后台线程池的调度程序来进行查询,因此您不需要像这样手动切换上下文,您只需从 UI 线程调用它即可。
旁注:MainScope().launch { .. }像这样使用是一个坏主意,因为它遇到与GlobalScope. 要正确使用它,您需要将此范围提取到变量/属性中,以便您可以在适当的时候取消它。也就是说,使用现有范围更容易。Android已经在具有生命周期的 Activity 等组件中提供了随时可用的协程作用域lifecycle-runtime-ktx(请参阅库)。它被称为lifecycleScope. 您应该在此范围内启动协程,以便在活动被销毁时它们会自动取消。
| 归档时间: |
|
| 查看次数: |
6706 次 |
| 最近记录: |