Kotlin - 运行 ksoap2 作为协程与异步 - 哪个更好?

Kotlin - running ksoap2 as a coroutine vs async - which is better?

Android 和 Kotlin 新手 - 我有一个调用 SOAP Web 服务的应用程序。现在调用是使用 Thread 进行的,并且通信正常。我想将其移至 Kotlin 协程或 Android 异步任务,我的问题是 - 在这种情况下哪个更好?

我已经尝试根据这篇文章创建协程调用 https://proandroiddev.com/how-to-make-sense-of-kotlin-coroutines-b666c7151b93,基本上适应这种模式:

fun main() = runBlocking {
    val deferredResult = async {
        delay(1000L)
        "World!"
    }
    println("Hello, ${deferredResult.await()}")
}

当我将 Web 服务调用置于协程异步中时,Android Studio 突出显示 HttpTransportSE 调用方法 (http://www.kobjects.org/ksoap2/doc/api/org/ksoap2/transport/HttpTransportSE.html) 并显示以下警告:

不适当的阻止方法调用。报告在不应阻塞线程的代码片段中发现的线程阻塞方法调用

我对这条消息的理解是,HttpTransportSE 的调用阻塞了线程,因此我们失去了使用协程的优势,我应该坚持异步任务。 这种解释是否正确,或者是否有一种方法可以将调用与协程包装在一起,从而更有效地工作?

下面是我的代码(它与网络服务通信,但由于警告,我觉得这不是执行此操作的正确方法):

fun callWebService(
...
): String {
    val defferedResult: Deferred<String> = GlobalScope.async {
        try {
...
            val envelope = SoapSerializationEnvelope(SoapEnvelope.VER12)
...
            val androidHttpTransport = HttpTransportSE(URL)
            androidHttpTransport.debug = true
            androidHttpTransport.call("$NAMESPACE/$methodName", envelope)    //this is where I get the warning
            val resultData = envelope.response
            webResponse = "$resultData"
...
        }
        return@async webResponse
    }
    return runBlocking { defferedResult.await() }
}

我想我已经弄明白了,多亏了这个article
它归结为 运行 在后台使用 Dispatchers.IO
SOAP 调用可以是常规函数,不需要 Deffered 等

我正在使用带有存储库的 MVVM 模型,因此所有后台工作都在 Repository 级别上进行,由在相应 ViewModel 中启动的 Fragment 中的按钮触发,范围有限

我的 SOAP 调用现在看起来像这样

fun callWebService(...): String {
        try {
...
            val envelope = SoapSerializationEnvelope(SoapEnvelope.VER12)
...
            val androidHttpTransport = HttpTransportSE(URL)
            androidHttpTransport.debug = true
            androidHttpTransport.call("$NAMESPACE/$methodName", envelope)    
            val resultData = envelope.response
            webResponse = "$resultData"
...
        }
        return webResponse
}

Repository 我有以下功能 - 注意 suspendDispatchers.IO

    suspend fun insertAndSend(task: Task) {
        withContext(Dispatchers.IO) {
            val response = callWebService(processedTask)
            processedTask.status = response
            taskDao.update(processedTask)
        }
    }

ViewModel中我在ViewModelScope

中调用了Repository函数
//defined in ViewModel class
 fun insertAndSend(task: Task) = viewModelScope.launch { repository.insertAndSend(task) }

在相应的Fragment中通过按下按钮

触发