为什么不建议使用 GlobalScope?

  • 当我们使用GlobalScope启动协程时,它将在顶级协程中启动,因为它是全局的,并且会一直保留到您的应用程序死掉为止。

换句话说:

  • 如果你 GlobalScope用来启动一个协程,即使你跳过了特定的活动,它也会一直存活到你的应用程序死掉 || 启动特定 Corotuine 的片段。
  • 正如您已经知道的那样,协程是轻量级的,但Will Consume Some Memory Resources在它肯定运行时仍然如此,这可能会导致您的应用程序中的内存泄漏。

解决方案

  • 您可以使用预定义的范围,例如lifecycleScope{…},如果您正在使用 ViewModel(s),您可以使用viewModelScope{…}它来启动协程并开始使用。

实际差异

让我们测试两者GlobalScope{…}并lifecycleScope{…}更好地理解

  • 我创建了两个片段并通过导航组件在两个片段之间添加了导航。

第一个片段的 XML:

android kotlin 获取国家码 kotlin globalscope_无限循环


第二个片段的 XML:

android kotlin 获取国家码 kotlin globalscope_android_02


讲真话的时间🔥

在进一步Make Sure说明您已包含协程依赖项(如果未包含)之前:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'

在 First Fragment 的 Kotlin 文件中:

在GlobalScope{…}

  • GlobalScope{…}当按下按钮时,主要协程将被启动。
  • 当按下按钮时,每次都会以第二个延迟运行无限循环。
  • 延迟 5 秒后,将启动第二个片段,如下代码所示:
view.toSecondFragment.setOnClickListener {
       GlobalScope.launch{
         while (true) {
              delay(1000L)
              Log.d("From GlobalScope", "Global Scope Is Still Running")
     }
 }

      GlobalScope.launch(Dispatchers.Main){
         delay(5000L)
         Navigation.findNavController(view).navigate(R.id.firstFragment_to_secondFragment)
      }
}
  • 现在在成功构建后启动应用程序:

android kotlin 获取国家码 kotlin globalscope_应用程序_03

  • 正如你所看到的,即使第一个片段已经死了,我们的循环仍然继续,因为我们声明了我们的范围,GlobalScope{…}它将继续运行,直到我们的应用程序死了。
  • 这是在 Kotlin-Coroutines 中不鼓励使用 GlobalScope 的主要原因。

在lifecycleScope{…}

  • lifecycleScope{…}当按下按钮时,主要协程将被启动。
  • 当按下按钮时,每次都会以第二个延迟运行无限循环。
  • 延迟 5 秒后,将启动第二个 Fragment。

正如您viewLifecycleOwner在启动协程之前提到的代码中所见lifecycleScope{…}

  • 这是因为我正在处理片段。viewLifecycleOwner当 Fragment 有它的 UI 时添加 ( onCreateView() , onDestroyView() )这是添加到 Fragment 的整体生命周期( onCreate() , onDestroy() )。
  • 以防万一,如果您正在从事活动,则无需提及viewLifecycleOwner。
view.toSecondFragment.setOnClickListener {
            viewLifecycleOwner.lifecycleScope.launch{
                while (true) {
                    delay(1000L)
                    Log.d("From LifeCycleScope", "LifeCycleScope Is Still Running")
                }
            }
           viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main){
                delay(5000L)
                Navigation.findNavController(view).navigate(R.id.firstFragment_to_secondFragment)
            }
        }
  • 现在在成功构建后启动应用程序:

android kotlin 获取国家码 kotlin globalscope_应用程序_04

  • 如您所见,一旦片段死亡,协程执行就停止了。

同样意味着viewModelScope{…}同样,它也将执行与 相同lifecycleScope{…}。但是viewModelScope{…}当你使用 ViewModel(s) 时你会用到。

结论

  • 当您希望操作GlobalScope{…}运行直到应用程序死机时使用,如果不是,您绝对应该使用lifecycleScope{…}.
  • 如果您正在使用 ViewModel(s),您可以使用viewModelScope{…}.

最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。