首页 > 解决方案 > 从片段中的点击事件启动协程

问题描述

从片段中定义的点击事件启动协程的正确方法是什么?据我了解,GlobalScope.launch如果您想启动一个应该在应用程序的整个生命周期内保留在内存中的协程,则使用该协程。但是由于片段的生命周期通常比应用程序短,因此GlobalScope.launch可能不是正确的方法。我假设如果我使用GlobalScope.launch,它可能会阻止碎片被垃圾收集?

我真的只需要从单击事件处理程序启动协程,这意味着我不会从中调用任何父函数。

标签: kotlinkotlin-coroutines

解决方案


您需要job处理协程取消以防止泄漏:

//inside Fragment
val job = Job()
val uiScope = CoroutineScope(Dispatchers.Main + job)


//late in the button click

button.setOnClickListener{
  uiScope.launch(Dispatchers.IO){
    //asyncOperation
    withContext(Dispatchers.Main){
     //ui operation
   }

  }
}

//later in on destroy:

override fun onDestroy(){
  job.cancel()
  super.onDestroy()
}

您还可以使用Google 的LifecycleScope 扩展

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        lifecycleScope.launch {
            val params = TextViewCompat.getTextMetricsParams(textView)
            val precomputedText = withContext(Dispatchers.Default) {
                PrecomputedTextCompat.create(longTextContent, params)
            }
            TextViewCompat.setPrecomputedText(textView, precomputedText)
        }
    }
}

编辑,以防您重新启动另一个操作。只需使用相同的范围:

//let's assume you have a second button

button2.setOnClickListener{
  uiScope.launch(Dispatchers.IO){
    //perform second operation
  }
}

推荐阅读