按键分析--APP部分-- OnLongClickListener事件处理流程
来源:互联网 发布:qq浏览器链接不了网络 编辑:程序博客网 时间:2024/05/17 14:25
5.4 OnLongClickListener事件处理流程
5.4.1 OnLongClickListener注册和使用
其注册和使用方法和OnClickListener相似,在activity里实现接口,
public class Launcher extends Activity
implements View.OnLongClickListener,
view设置监听器,
mWorkspace.setOnLongClickListener(this);
view基类里调用performLongClick,执行onLongClick()
public boolean performLongClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
boolean handled = false;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnLongClickListener != null) {
handled = li.mOnLongClickListener.onLongClick(View.this);
}
if (!handled) {
handled = showContextMenu();
}
if (handled) {
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
return handled;
}
5.4.2 OnClickListener栈分析
栈的调用过程和OnClickListener也类似,用异步的方式调用到activity的onLongClick方法,
Launcher.onLongClick(View) line: 5169
CellLayout(View).performLongClick() line: 5244
View$CheckForLongPress.run() line: 21138
Handler.handleCallback(Message) line: 739
ViewRootImpl$ViewRootHandler(Handler).dispatchMessage(Message) line: 95
Looper.loop() line: 148
ActivityThread.main(String[]) line: 5524
Method.invoke(Object, Object...) line: not available [native method]
ZygoteInit$MethodAndArgsCaller.run() line: 752
ZygoteInit.main(String[]) line: 642
所以我们看一下消息是如何post出来的即可。
在Android的触摸消息中,已经实现了三种监测,它们分别是
1)pre-pressed:对应的语义是用户轻触(tap)了屏幕
2)pressed:对应的语义是用户点击(press)了屏幕
3)long pressed:对应的语义是用户长按(long press)了屏幕
下图是触摸消息随时间变化的时间轴示意图:
其中,t0和t1定义在ViewConfiguration类中,标识了tap和longpress的超时时间,定义如下:
private static final int TAP_TIMEOUT = 100;
private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500;
在早期版本中,在View类的OnTouchEvent函数中,当View监测到ACTION_DOWN事件时,首先发送一个延迟为t0的异步消息处理tap,在Android6.0中则不使用这种机制了。
长按的调用栈:
onTouchEvent --checkForLongClick –post
—CheckForLongPress--run --performLongClick-- .mOnLongClickListener.onLongClick
如前分析,在onTouchEvent的MotionEvent.ACTION_DOWN,执行checkForLongClick,延时post一个长按消息出去。
case MotionEvent.ACTION_DOWN:
mHasPerformedLongPress = false;
// Walk up the hierarchy to determine if we're inside a scrolling container.
boolean isInScrollingContainer = isInScrollingContainer();
// For views inside a scrolling container, delay the pressed feedback for
// a short period in case this is a scroll.
if (isInScrollingContainer) {
mPrivateFlags |= PFLAG_PREPRESSED;
if (mPendingCheckForTap == null) {
mPendingCheckForTap = new CheckForTap();
}
mPendingCheckForTap.x = event.getX();
mPendingCheckForTap.y = event.getY();
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
} else {
// Not inside a scrolling container, so show the feedback right away
setPressed(true, x, y);
checkForLongClick(0);
}
break;
在MotionEvent.ACTION_UP及MOVE\CANCEL中, 会清除长按的异步消息,设置相关的变量和按键状态,这样,如果这些事件产生在长按超期前,长按就不起作用;在长按超期后,长按有效,并完成了按键的周期流程。所以按键处理的逻辑就是这样的。
removeLongPressCallback();
setPressed(false);
onClick和onLongClick能同时发生吗?
要理解Android对事件处理的所谓消费(consume)概念即可,一个用户的操作会被传递到不同的View控件和同一个控件的不同监听方法处理,任何一个接收并处理了该次事件的方法如果在处理完后返回了true,那么该次event就算被完全处理了,其他的View或者监听方法就不会再有机会处理该event了。
onLongClick的发生是由单独的线程完成的,一般发生在ACTION_UP之前,而onClick的发生是在ACTION_UP后。临界条件是同时发生,这里会有flag来进行区分。
因此同一次用户touch操作就有可能既发生onLongClick又发生onClick。
及时向系统表示“我已经完全处理(消费)了用户的此次操作”,是很重要的事情。
另外一个同时执行的概念(都执行的意思),先后执行,例如,我们如果在onLongClick()方法的最后return true,那么onClick事件就没有机会被触发了。
在onLongClick()方法return false的情况下,一次触碰操作的基本时序:
04-05 06:00:53.023: DEBUG/TSActivity(277): onTouch ACTION_DOWN
04-05 06:00:53.533: DEBUG/TSActivity(277): onLongClick
04-05 06:00:55.603: DEBUG/TSActivity(277): onTouch ACTION_UP
04-05 06:00:55.663: DEBUG/TSActivity(277): onClick
可以看到,在ACTION_UP后仍然触发了onClick()方法。
- 按键分析--APP部分-- OnLongClickListener事件处理流程
- 按键分析--APP部分-- OnTouch事件处理流程
- 按键分析--APP部分-- OnClickListener事件处理流程
- Android按键事件处理流程
- Android按键事件处理分析 .
- Android按键事件处理分析
- Android按键事件处理流程 KeyEvent
- Android按键事件处理流程 -- KeyEvent
- Android按键事件处理流程 -- KeyEvent
- Android按键事件处理流程 -- KeyEvent
- Android Activity的按键事件处理流程
- Android按键事件处理流程 -- KeyEvent
- ZStack协议按键处理流程分析
- qt按键事件处理机制分析
- Android事件处理流程分析
- Android事件处理流程分析
- (转载)收集android事件处理,按键、触摸屏部分
- Android按键事件处理流程 -- 从事件被派发到View层次结构的根节点DecorView开始分析
- java 反射获取所有类文件
- 计算机专业英语 学习笔记 3
- 使用PHP+Sphinx建立高效的站内搜索引擎
- Centos搭建LNMP环境
- Spring面试知识点总结
- 按键分析--APP部分-- OnLongClickListener事件处理流程
- iOS 开发 :Multimedia开发简介
- Tk::Table
- 使用 libevent 和 libev 提高网络应用性能
- Android studio reset adb操作
- IOS为图片截图
- 谷歌图像识别API向所有开发者开放
- Zoho Books:经常性交易自动扣款
- 115个Java面试题和答案——(上)