首页 > 解决方案 > 从活动调用协程函数返回“只能从协程或另一个挂起函数调用”

问题描述

我正在尝试coroutines在我的代码中使用,因为在我的一个函数中,我需要进行多个网络调用并等待其结果。以下是我的活动代码的一部分:

class SellerDeliveryRegister : AppCompatActivity() {

    lateinit var sellerDeliveryVM:SellerDeliveryVM

    sellerDeliveryVM = ViewModelProviders.of(this).get(SellerDeliveryVM::class.java)

    var uploadVehicleImageResult = sellerDeliveryVM.uploadVehiclesImages(uploadMotorImage1Url,uploadMotorImage2Url)
}

以下是我的sellerDeliveryVMViewModel 代码的一部分:

class SellerDeliveryVM: ViewModel() {
    suspend fun uploadVehiclesImages(uploadMotorImage1Url: String, uploadMotorImage2Url: String): Unit = withContext(Dispatchers.IO){

        var uploadMotorImage1Result = "-1"; var uploadMotorImage2Result = "-1"; 
        viewModelScope.launch(Dispatchers.IO) {

            uploadMotorImage1Result = withContext(Dispatchers.Default) {
                NetworkRepository.instance!!.uploadFile(uploadMotorImage1Url)
            }

            uploadMotorImage2Result = withContext(Dispatchers.Default) {
                NetworkRepository.instance!!.uploadFile(uploadMotorImage2Url)
            }

            return@launch;
        }
        return@withContext
    }
}

请注意,以前uploadVehiclesImages是一个不使用协程的“普通”函数,所以现在我将其转换为使用协程。

以下是我面临的问题:

  1. var uploadVehicleImageResult = sellerDeliveryVM.uploadVehiclesImages(uploadMotorImage1Url,uploadMotorImage2Url)我班级内的行SellerDeliveryRegister返回此错误:

Suspend function 'uploadVehiclesImages' should be called only from a coroutine or another suspend function

  1. 最初我想Boolean从中返回,uploadVehiclesImages所以我return truereturn@launchreturn false代替了.return@withContextreturn is not allowed here

那么我应该怎么做才能解决这个问题 1,任何人都可以告诉我更多关于问题 2 的实际情况吗?

标签: androidkotlinkotlin-coroutines

解决方案


那么我应该怎么做才能解决这个问题 1

删除属性。uploadVehiclesImages()返回UnitUnit拥有财产没有任何价值。如果您的目标是在uploadVehiclesImages()创建视图模型时调用,请将调用放在一个init块中,并包装在一个合适的协程启动器中(例如,viewModelScope.launch {})。

这假设您要将函数保持在当前形式 - 您的下一个问题表明此函数可能不是正确的解决方案。

最初我想从uploadVehiclesImages返回布尔值,

更重要的是,您似乎希望它多次返回值。这不是函数在 Kotlin 中的工作方式。一次调用uploadVehiclesImages()可以返回一个 Boolean值,但不是现在一个,也不是将来某个时候。

如果你想发出一个结果流,一个suspend函数本身不是正确的解决方案。例如,您可以:

  • 使用LiveData, 与suspend更新支持的功能MutableLiveData,或

  • 使用返回StateFlow或的函数SharedFlow


推荐阅读