我正在创建一个Android/Windows远程控制应用程序的第二个版本,使用Kotlin作为客户端和服务器。我对Android上的协同程序的基础知识很熟悉,但令我惊讶/不幸的是,协同程序在两个平台上的表现不同。我测试了完全相同的代码,在Android上可以正常工作,但在电脑上什么也没有发生
主要.kt
fun main(): Unit = runBlocking {
CoroutineScope(Job()).launch {
println("connecting server")
Servidor.ligar()
}
CoroutineScope(Job()).launch {
println("connecting client")
Cliente.ligar()
}
}
服务器.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()
}
}
客户端.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()
}
}
客户端/服务器连接的代码工作完美,当从Android中的一个Activity执行时。
这是在android(Android Studio)上运行代码时Logcat的输出:
connecting server
connecting client
Trying to connect through 1777...
initialize
Connected by port: 1777
The message: initialize
Server returns initialize
The message: bye
bye
这是代码在Windows上运行时的Logcat输出(Intellij IDEA)
connecting server
calling customer
Process finished with exit code 0
我显然不知道如何处理android环境之外的协程,我怎样才能使它按预期工作呢?
Ps:以下是我在桌面版应用程序上使用的库列表:
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4
1条答案
按热度按时间llew8vvj1#
您不会等待已启动的协程。当您在
runBlocking
中时,它只会阻塞以等待其已启动的子进程。但您正在创建新的协程作用域以启动协程,因此它们不是runBlocking
协程的子进程。它们会被异步触发。然后runBlocking
返回,您的应用立即终止。