What is the proper way to launch a coroutine from a click event that is defined in a fragment? From my understanding, GlobalScope.launch is used if you want to launch a coroutine that is supposed to remain in memory for the entire lifecycle of the app. But since a fragment usually has a shorter lifecycle than the app, GlobalScope.launch probably isn't the proper way. I assume that if I used GlobalScope.launch, it might keep the fragment from being garbage collected?

我真的只需要从点击事件处理程序启动协同程序,这意味着没有父函数可以调用.

推荐答案

You need a job to handle the coroutine cancelation to prevent leaks:

//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()
}

你也可以使用谷歌的LifecycleScope extension:

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
  }
}

Kotlin相关问答推荐

如何更改默认推断没有接收者的函数类型?

kotlin短路列表判断吗?

Kotlin - 如何避免在密封类的 when() 语句中转换第二个变量

Kotlin 可空泛型

Kotlin 函数有 2 个参数用于对 Map 或 List 进行排序

Kotlin 中的密封和内部有什么区别?

Kotlin RxJava 可空的错误

interface扩展

Map.mapTo 到另一个map

Gradle 同步失败:不支持的方法:KotlinPlatformContainer.supports()

验证和 DDD - kotlin 数据类

Kotlin 与 C# 中的标志枚举变量具有相似效果的方式是什么

通过在 kotlin-gradle 中使用子项目Unresolved reference: implementation

如何在不绑定ViewModel(MVVM)中的UI的情况下使用android导航?

我应该在哪里调用 MobileAds.initialize()?

带有注释为@RegisterExtension的字段的 JUnit 5 测试在 Kotlin 中不起作用

Kotlin:获取文件的扩展名,例如.txt

是否可以在不使用class的情况下将 Mockito 与 Kotlin 一起使用?

Kotlin for assertThat(foo, instanceOf(Bar.class))

RxJava2 UndeliverableException 在获取数据时发生方向变化