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

问题描述 投票:1回答:1

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() }
}

android kotlin async-await android-ksoap2
1个回答
0
投票

由于这个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中触发

© www.soinside.com 2019 - 2024. All rights reserved.