先简单说明下在客户端中,消息的总体派发机制:
在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); }
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()函数。