先简单说明下在客户端中,消息的总体派发机制:
在ViewRootImpl.java的handleMessage()是处理所有消息的地方,其中MSG_PROCESS_INPUT_EVENTS对应于按键消息,触摸消息,滚轮消息和摇杆消息。接收到这个消息后,调用doProcessInputEvents(),这个函数再调用deliverInputEvent()分发具体消息,其中触摸消息对应于deliverPointerEvent()。在这个函数中会先对消息进行一些处理然后再派发给根视图mView.dispatchPointerEvent(event)。这个mView是PhoneWindow中的DecorView。
PhoneWindow.DecorView
public boolean dispatchTouchEvent(MotionEvent ev) {
final Callback cb = getCallback();
return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
: super.dispatchTouchEvent(ev);
}
这里首先判断是否存在Callback对象,即Activity对象。如果有:cb.dispatchTouchEvent()
Activity
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();//这里什么也没做交给用户有需要的时候在处理ACTION_DOWN事件之前做点什么
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);//这里面什么也没做,交给用户处理。
}
如果有window对象,接着调用Window.java中的superDispatchTouchEvent,而实现Window中的这个函数的类是PhoneWindow
PhoneWindow
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
因此又回到了DecorView中调用superDispatchTouchEvent而该函数调用了ViewGroup中的dispatchTouchEvent()函数。此处如果没有消化掉这个消息,则调用onTouchEvent()处理事件。
上面如果不存在Callback对象,则直接调用了ViewGroup中的dispatchTouchEvent()函数。