Home > front end >  coroutines behave differently on Android/JVM (for windows)
coroutines behave differently on Android/JVM (for windows)

Time:01-04

I'm creating a second version of an Android/Windows remote control app using kotlin for client and server. I'm familiar with the basics of coroutines on android but to my surprise/unfortunateness, coroutines have behaved differently on the two platforms. I tested the EXACT same code and on android it just works but on the computer nothing happens

Main.kt

fun main(): Unit = runBlocking {

    CoroutineScope(Job()).launch {
        println("connecting server")
        Servidor.ligar()
    }

    CoroutineScope(Job()).launch {
        println("connecting client")
        Cliente.ligar()

    }

}

Server.kt

object Servidor {

    suspend fun ligar() = withContext(Dispatchers.IO) {

        val porta = 1777
        var mensagem: String

        val server = ServerSocket(porta)
        println("Trying to connect through $porta...")

        val client = server.accept()
        val mPrintWriter = PrintWriter(client.getOutputStream(), true)

        val br = BufferedReader(InputStreamReader(client.getInputStream()))
        println("Connected by port: $porta")

        while (br.readLine().also { mensagem = it } != null) {
            println("The message: $mensagem")
            if (mensagem == "bye") {
                mPrintWriter.println("bye")
                break
            } else {
                mensagem = "Server returns $mensagem"
                mPrintWriter.println(mensagem)
            }
        }
        mPrintWriter.close()
        br.close()

        client.close()
    }
}

Client.kt

object Cliente {

    suspend fun ligar() = withContext(Dispatchers.IO) {

        val portNumber = 1777
        var str = "initialize"

        val mSocket = Socket(InetAddress.getLocalHost(), portNumber)
        val br = BufferedReader(InputStreamReader(mSocket.getInputStream()))
        val pw = PrintWriter(mSocket.getOutputStream(), true)

        pw.println(str)
        println(str)

        while (br.readLine().also { str = it } != null) {
            println(str)
            pw.println("bye")
            if (str == "bye") break
        }
        br.close()
        pw.close()
        mSocket.close()
    }

}

The code for client/server connection works perfectly, when executed from an activity in android.

This is the output from Logcat when the code is run on android (Android Studio):

connecting server
connecting client
Trying to connect through 1777...
initialize
Connected by port: 1777
The message: initialize
Server returns initialize
The message: bye
bye

This is the Logcat output when the code is run on windows (Intellij IDEA)

connecting server
calling customer

Process finished with exit code 0

I'm clearly not knowing how to deal with coroutines outside the android environment, how can i make this work as intended?

Ps: Here is the list of libraries i'm using on desktop version on app:

org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4

CodePudding user response:

You are not waiting for your launched coroutines. When you are in a runBlocking, it only blocks to wait for it’s launched children. But you are creating new CoroutineScopes for launching coroutines, so they are not children of the runBlocking coroutine. They are fired off asynchronously. Then runBlocking returns and your app terminates immediately.

  • Related