![](/img/trans.png)
[英]When dealing with WebServices in Android which approach would be better KSOAP2 or Android default HTTPClient
[英]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的調用阻塞了線程,因此我們失去了使用協程的優勢,我應該堅持Async任務。 這種解釋是否正確,或者是否有一種使用協程包裝調用的方法可以更正常地工作?
下面是我的代碼(它與網絡服務通信,但由於警告,我覺得這不是執行此操作的正確方法):
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() }
}
我想我已經想通了,多虧了這篇文章
它歸結為使用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
我稱之為Repository
的內功能ViewModelScope
//defined in ViewModel class
fun insertAndSend(task: Task) = viewModelScope.launch { repository.insertAndSend(task) }
通過按下按鈕在相應的Fragment
觸發
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.