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
我有以下功能 - 注意 suspend
和 Dispatchers.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
中通过按下按钮
触发
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
我有以下功能 - 注意 suspend
和 Dispatchers.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
中通过按下按钮