【发布时间】:2019-11-17 20:05:42
【问题描述】:
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
val status = operation() // operation takes time
return status
}
return super.onKeyDown(keyCode, event)
}
当一个事件发生时,上面的处理程序被调用。现在如果需要时间来决定是否将true 或false 状态传递到 if 块内的下一层(超级),如何正确设计流程。我需要得到结果asynchronously,因为决定返回值的时间(即true 或false)可能会更长,并且函数不应该让主线程等待。所以,我需要想办法让超级调用延迟。
解决这个问题的正确方法是什么?有什么特定的设计模式来处理这类问题吗?
请忽略语言。
更新 1
我一直在考虑存储keyCode 和event 并立即返回true(意味着事件已被其他观察者重新消费),然后在operation() 完成后我有status 可用,现在我可以使用相同的 keyCode 和 event 重新触发挂起的存储事件。但并非所有事件都提供手动触发的功能。对于无法手动触发的事件,我该怎么做。
我提出的解决方案
private fun doOperation(callback: (status:Boolean) -> Unit) {
Handler().postDelayed({
callback.invoke( arrayOf(true, false).random() )
}, 5000)
}
var pendingEvent: KeyEvent? = null
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
doOperation {
if (it && pendingEvent != null){
dispatchKeyEvent(pendingEvent)
pendingEvent = null
} else {
// do nothing
}
}
return true // let other know I consumed it
}
return super.onKeyDown(keyCode, event)
}
这是正确的方法吗?这种想法有什么坏处?
【问题讨论】:
-
你的意思是你不知道
onKeyDown应该返回true还是false? -
@Blackbelt 我将知道需要延迟的异步操作(比如说来自网络应用程序的服务器调用)之后的返回值。但这是一个 f/w 回调,需要同步并立即传递 true 或 false。
-
AFAIK,这是不可能的。你不能在不阻塞主线程的情况下延迟返回语句。
-
@karandeepsingh 我知道这是不可能的。我一直在寻找解决办法。
-
现在,一分钟后,长时间运行的动画停止了,
onAnimationStopped处理程序被调用。在此处理程序中,您首先取消订阅animationStopped事件。然后检查按下了哪个键来决定启动哪个动画并启动适当的新动画。现在你已经等待而没有阻塞任何东西。存储第一个事件的结果或事件参数,以便延迟操作(事件处理程序ònAnimationCompleted`)稍后可以使用它。
标签: android events design-patterns event-handling observer-pattern