gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 13:44:54 25 4
gpt4 key购买 nike

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

我尝试根据本文创建协程调用
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进行的调用会阻塞线程,因此我们失去了使用协程的优势,我应该坚持使用Async任务。
这种解释是正确的,还是有一种方法可以用更合适的协程将调用包装起来?

下面是我的代码(它与Web服务通信,但是由于警告,我感觉这不是执行此操作的正确方法):
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级别上进行,这是由在相应Fragment中启动的ViewModel中的按钮按下触发的,范围有限

我的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中,我在 Repository中调用了 ViewModelScope函数
//defined in ViewModel class
fun insertAndSend(task: Task) = viewModelScope.launch { repository.insertAndSend(task) }

按下按钮即可在相应的 Fragment中触发

关于android - Kotlin-将ksoap2作为协程vs异步运行-哪个更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59715382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com