我有点糊涂了. 我知道如果一个函数想要使用协程,它应该被声明为挂起 例如:

 private suspend fun doSomething() {  
      withContext(Dispatchers.IO) {      
   //do something 
 } }

我也知道有这样一种方法,可以在不暂停功能的情况下使用协程. 比如:

 private fun doSomething1() {      
    CoroutineScope(Dispatchers.IO).launch { 
          //do something  
} }

这两个功能有什么不同? 什么时候用第一个例子,什么时候用第二个例子?

推荐答案

这两个功能有什么不同?

两者之间有两个主要区别:

  • 用法不同:suspend型给人的感觉是同步的,而launch型则是明显的异步型
  • 第二个函数 destruct 了 struct 化并发,不应该以这种方式编写

让我详细说明一下.

从使用的Angular 来看,suspend函数看起来是同步的:当您调用它时,下一行代码仅在函数完成时执行(与任何其他常规函数一样).这使得推理变得很容易.您甚至可以将suspend函数的返回值赋给一个变量,然后继续您的生活,就像该函数不是suspend一样.当然,当你已经处于suspend的上下文中时.如果不是,则必须使用显式的协程构建器(如launchasyncrunBlocking)启动"根"协程.

当使用launch时,您显式地启动了一个异步任务,因此launch之后的代码与launch中的代码并发运行.因此,反过来,当调用doSomething1()时,它之后的代码将与内部launch中的任何内容并发运行.然而,从API的Angular 来看,确实不清楚该函数是否会启动比它更持久的任务.这也符合这样一个事实,即您不应该创建这样的"免费"协程作用域.我将在下面详细说明.

什么时候用第一个例子,什么时候用第二个例子?

尽可能多地使用suspend个函数以使事情变得简单.在大多数情况下,您不需要启动比函数调用持续时间更长的任务,因此这是非常好的.通过使用coroutineScope { ... }启动一些协程,您仍然可以并发地执行一些工作inside your suspend function.这不需要外部提供的作用域,而且从调用者的Angular 来看,所有计算都将在Suspend函数调用中进行,因为coroutineScope {}将等待子协程完成,然后才返回.

这里使用launch的函数的行为非常糟糕,你永远不应该写这样的东西:

  • 不应该当场制造CoroutineScope个,然后留在那里等死.你应该控制它,并在适当的时候取消它
  • 如果在调用此函数时已处于挂起状态,则现有的协程上下文和作业(job)将被忽略

为了避免这些问题,您可以通过将CoroutineScope设置为接收器而不是现场创建接收器来显式地使用API:

private fun CoroutineScope.doSomething1() {      
    launch(Dispatchers.IO) { 
          //do something  
    }
}

但只有在函数的本质是启动在函数返回后继续运行的东西时,才使用这种方法.

Android相关问答推荐

理解修饰符<;方法>;与修饰符<;方法>;:效果和行为解释(Android开发者Jetpack Compose)

合成-删除图像的部分背景

我到底应该如何分享我的应用程序中的图片?

每次重启Android时预填入Room数据库

Play Google上发布的一款应用的房间数据库迁移

为什么我在 android 中使用 TabLayout 时无法启动我的 Activity?

Android Compose - 为什么 Canvas 中的drawText在底部被切断而不是在顶部?

警告:应用必须面向 Android 13(API 级别 33)或更高版本.确实如此

如何将DrawableId参数传递给XML布局?

块不起作用,出现 "只有安全的 (?.)... " 错误

当 Firebase Firestore 发生变化时,Kotlin ViewModel 不会更新

在 compose 中做可变状态堆栈

根据另一个数组的值对数组进行排序

如何在 android compose 中将具有渐变边缘的透明圆圈绘制到阴影覆盖层中?

找不到(包名称).在以下位置搜索:

是否可以在 Kotlin 中为 mutableStateOf() 设置自定义设置器

android 13 版本是否会影响 android 12 目标应用程序

为什么我不能在屏幕外拿任何物体

Android Compose webview 被拉伸

升级到 android studio 花栗鼠后,应用程序未安装在模拟器中