Android and Kotlin noob here - I have an app calling a SOAP web service. Right now the calls are made using Thread and communication is working. I would like to move that to either Kotlin coroutines or Android Async tasks, my question is - which is better in this case?
I've tried creating a coroutine call based on this article https://proandroiddev.com/how-to-make-sense-of-kotlin-coroutines-b666c7151b93, basically adapting this pattern:
fun main() = runBlocking {
val deferredResult = async {
delay(1000L)
"World!"
}
println("Hello, ${deferredResult.await()}")
}
When I put the web service call in the coroutine async, then Android Studio highlights the HttpTransportSE call method (http://www.kobjects.org/ksoap2/doc/api/org/ksoap2/transport/HttpTransportSE.html) with the following warning:
Inappropriate blocking method call. Reports thread-blocking method calls found in a code fragment where a thread should not be blocked"
My understanding of this message is that the call made by the HttpTransportSE blocks the thread, therefore we lose the advantage of using coroutines, and I should just stick to the Async task. Is that interpretation correct, or is there a way of wrapping the call with coroutine that would work more properly?
Below is my code (it communicates with the web services, but because of the warning I have a feeling it's not a proper way to do this):
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() }
}
I think I have figured it out, thanks to this article
it comes down to running in the background using
Dispatchers.IOthe SOAP call can be regular function, no need for Deffered, etc.
I am using MVVM model with repository, so all the background work is happening on the
Repositorylevel, triggered by button press in theFragmentlaunched in the respectiveViewModel, with limited scopemy SOAP call now looks like this
in the
RepositoryI have following function - note thesuspendandDispatchers.IOin the
ViewModelI call theRepositoryfunction within theViewModelScopewhich is triggered in the respective
Fragmentby pressing a button