【问题标题】:Getting "suspend function can only be called within coroutine body" when calling a suspend function from another suspend function [duplicate]从另一个挂起函数调用挂起函数时,获取“只能在协程主体内调用挂起函数”[重复]
【发布时间】:2020-11-07 18:11:18
【问题描述】:

我正在使用 Room 在本地缓存我的用户购买。为此,我创建了一个 insert 函数,该函数正在暂停。

首先,在我的存储库中,我从一个名为 launchBillingFlow 的函数调用了 insert 函数,该函数处于挂起状态,其签名如下所示:

suspend fun launchBillingFlow(activity, skuDetails)

我这样做没有任何错误。之后,我创建了一个private 函数来确认购买并将insert 调用移到那里。它的签名是这样的:

private suspend fun acknowledgePurchase(purchase)

但是当我从那里调用插入函数时,出现以下错误:

Suspension functions can be called only within coroutine body

我不明白为什么会这样。我从协程主体调用launchBillingFlow,它调用acknowledgePurchase。我也在做类似的事情来查询 SkuDetails。这是 lint 错误还是我遗漏了什么?

【问题讨论】:

  • 你确定你没有从 lambda 或回调中调用另一个挂起函数?
  • @Tenfour04 好点!我从ResponseListener 给它打电话,以确认购买是错误的。我将使用suspendCoroutine 来修复它。谢谢!
  • 顺便说一句,这不是 lint 错误,而是硬编译错误。 Kotlin 不可能在协程之外编译对可挂起函数的调用。

标签: android kotlin kotlin-coroutines


【解决方案1】:

这不是 lint 错误。 它说您的方法中需要协程上下文

lint 消息是:

suspend 函数只能在协程体

中调用

我知道suspend函数只能在另一个suspend函数内部调用 在协程内部。

相比之下,这条消息说只能在协程内部调用,但其实这并不矛盾。

要理解该消息,您可以忽略其中的挂起词并像这样阅读消息:

[函数名]只能在协程体中调用,因为它需要协程上下文。

它需要协程上下文的原因不是因为它被挂起而是因为在它里面你调用了一个需要上下文的方法。

【讨论】:

  • 我知道此信息。问题是,这是为什么呢?在某些时候,我只能从协程上下文中调用 suspend 函数。我在我的存储库中链接了其他 suspend 函数,在各种情况下它不会带来此错误。
  • 例如,当用户第一次打开显示我的报价的页面时,我通过BillingClient 查询SkuDetails,当我得到这些时,我将它们缓存在同一个数据库中另一个表使用基本相同的insert 函数。在这种情况下,lint 不会抱怨。
  • 而且lint 错误消息还暗示Suspension functions can be called only within coroutine body 通常是错误的,因为也可以从其他挂起函数调用挂起函数,因为我在我的代码中多次这样做。
  • 这个答案不正确。您始终可以从其他挂起函数调用挂起函数。每个挂起函数都从调用它的挂起函数中获取协程上下文。
  • @Tenfour04 我知道挂起函数只能在挂起函数或协程中调用,但是如果函数 A 和 B 都挂起,则您的评论不正确,这并不意味着您始终可以在 A 中调用 B,因为 B 可能需要一些 A 内部不可用的上下文或条件。A 处于挂起状态只是一个条件,可能还有其他条件。
猜你喜欢
  • 2019-05-24
  • 2021-06-05
  • 2020-11-18
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
相关资源
最近更新 更多