如何解决如何在Java中的函数内部等待函数调用?
我正在使用TCP服务器。对于登录操作,我有一个sendLogin和receiveLogin函数,但是我只想像这样调用一个函数。
fun login(login: String,pwd : String){
sendLogin(login,pwd)
onReceiveLogin((connected) =>
updateUiLogin(connected)
)
}
有可能吗?
编辑: 这是我的实际配置。
AbstractSocket-> SocketImplemented-> MainActivity
我想在SocketImplemented和MainActivity之间添加一个存储库。
AbstractSocket.kt
abstract class AbstractSocket(private val host: String,private val port: Int) : AbstractSocketInterface {
private var mOut: OutputStream? = null
lateinit var dis: DataInputStream
var packLeft: Int = 0
var connected = false
suspend fun init() {
withContext(IO) {
val socket = Socket()
try {
socket.connect(InetSocketAddress(host,port),1000)
val mIn: InputStream = socket.getInputStream()
mOut = socket.getOutputStream()
dis = DataInputStream(mIn)
onSocketConnected(this@AbstractSocket)
connected = true
while (connected) {
onMessageReceived()
if (packLeft > 0) {
println("Class:${this.javaClass.simpleName}\nSkipping bytes. N: $packLeft")
dis.skipBytes(packLeft)
}
if (packLeft < 0) {
println("Overrun on packet reading!")
connected = false
}
}
} catch (se: SocketException) {
println(
"Error + $se\n" +
"host:${host}\nport:${port}"
)
onSocketDisconnected(se)
} catch (sto: SocketTimeoutException) {
println(
"Error + $sto\n" +
"host:${host}\nport:${port}"
)
onSocketDisconnected(sto)
} finally {
socket.close()
}
}
}
suspend fun sendMessage(message: ByteArray) {
withContext(IO) {
mOut?.write(message)
mOut?.flush()
}
}
}
interface AbstractSocketInterface {
suspend fun onSocketConnected(abstractSocket: AbstractSocket)
suspend fun onSocketDisconnected(exception: Exception)
suspend fun onMessageReceived()
}
ImplementedSocket.kt
class ServerSocket private constructor(private val login: String,private val password: String,private val listenPort: Int,host: String,port: Int) : AbstractSocket(host,port) {
private val tag: String = this.javaClass.simpleName
private lateinit var serverSocketInterface: ServerSocketInterface
companion object {
private var instance: ServerSocket? = null
fun getInstance(login: String,password: String,listenPort: Int,port: Int): ServerSocket {
if (instance == null) // NOT thread safe!
instance = ServerSocket(login,password,listenPort,host,port)
return instance!!
}
}
override suspend fun onMessageReceived() {
this.packLeft = readInt()
val code = readInt()
println("Received: Message code:" + code + " Packet Size:" + (this.packLeft + 4))
when (code) {
1 -> receiveLogin()
}
}
private suspend fun receiveLogin() {
if (readBoolean()) {
val greeting = readString()
val ip = readInt()
println("Logged In.")
serverSocketInterface.onLogin(1,"connected",ip.toString())
} else {
val reason: String = readString()
this.connected = false
println("Login Failed:$reason")
}
}
private suspend fun login(login: String,pwd: String) {
try {
sendMessage(ByteMessage().write32(1)
.writeStr(login)
.writeStr(pwd)
.write32(160)
.writeStr(Bytes.md5(login + pwd))
.write32(1)
.buff)
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
}
}
fun setServerSocketInterface(callback: ServerSocketInterface) {
serverSocketInterface = callback
}
interface ServerSocketInterface {
suspend fun onLogin(connected: Int,greeting: String,ipAddress: String) {}
}
override suspend fun onSocketConnected(abstractSocket : AbstractSocket) {
abstractSocket as ServerSocket
login(login,password)
setListenPort(listenPort)
}
override suspend fun onSocketDisconnected(exception: Exception) {
Log.w(tag,"Disconnected from Server")
withContext(IO) {
Log.i(tag,"Trying to reconnect...")
this@ServerSocket.init()
}
}
}
MainActivity.kt
class MainActivity : AppCompatActivity(),ServerSocket.ServerSocketInterface {
/* Managers */
private lateinit var serverClient: ServerSocket
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
CoroutineScope(IO).launch {
launch(CoroutineName("ServerSocket")) {
serverClient = ServerSocket.getInstance(
"login","password","listenPort","host","port")
serverClient.setServerSocketInterface(this@MainActivity)
serverClient.init()
}
}
}
}
override fun onDestroy() {
super.onDestroy()
serverClient.stop()
}
override fun onBackPressed() {
super.onBackPressed()
finish()
}
/* SERVER SOCKET METHODS */
override suspend fun onLogin(connected: Int,ipAddress: String) {
withContext(Main) {
if (connected == 1) Toast.makeText(this@MainActivity,"Connected",Toast.LENGTH_SHORT).show()
else Toast.makeText(this@MainActivity,"Not Connected",Toast.LENGTH_SHORT).show()
}
}
}
所以现在我不想直接调用serverSocket方法,而是调用存储库以获取登录状态。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。