簡體   English   中英

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的調用阻塞了線程,因此我們失去了使用協程的優勢,我應該堅持Asy​​nc任務。 這種解釋是否正確,或者是否有一種使用協程包裝調用的方法可以更正常地工作?

下面是我的代碼(它與網絡服務通信,但由於警告,我覺得這不是執行此操作的正確方法):

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我有以下功能 - 注意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觸發

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM