Link:
Android Input (1) -- InputManagerService启动
Android Input (2) -- inputReader
Android Input (3) -- inputDispatcher
Android Input (4) -- inputDispatcher到ViewRootImpl
Android Input (5) -- ViewRootImpl 的事件分发(Activity ViewGroup View )
Android Input (6) -- PhoneWindowManager中Power,BACK等按键处理流程
Android Input (7) -- 模块的锁检测
Android Input (8) -- ANR input event原理
Android事件传递整体流程简介
Android输入事件的源头是位于/dev/input/下的设备节点,而输入事件的终点是由WMS管理的某个窗口,最终由窗口中的View处理。最初的输入事件为内核生成的原始事件,
而最终交付给窗口的则是KeyEvent(键盘)或MotionEvent(鼠标和触摸屏)对象。输入事件由Native层进入到Java层的第一个函数是InputEventReceiver.dispatchInputEvent(),
这样我们的手指触摸事件(MotionEvent)就传递到Java层,到应用层的传递过程遵循如下顺序:Activity->Window->View;即View事件最先传递给Activity,
然后由Activity传递给Window,最后由Window传递给View;顶级View(DecorView)接收到事件后,就会按照事件分发机制去分发事件;事件到达Java层以后是谁将事件传递给Activity?
//事件传递整体流程:底层生成原始事件后,经过一列加工处理之后,将事件封装成MotionEvent、keyEvent,然后传递到Java层的InputEventReceiver.dispatchTouchEvent中,
事件到达Java层之后,如何一步步传递到Activity?以下调用堆栈可以看到事件如何用从InputEventReceive传递到Activity;事件传递到Activity之后,由Activity传递给Window(PhoneWindow),
最后由Window传递给顶级View;顶级View(DecorView)接收到事件后,就会按照事件分发机制去分发事件;本文主要是从Activity开始来分析事件分发机制;
目录
Log Pattern1:
第3部分的流程图
第3部分的的Log pattern
1. 收到InputDispatcher事件的回调处理
1.1 handleEvent回调处理
1.2 NativeInputEventReceiver ::consumeEvents
1.3 gInputEventReceiverClassInfo.dispatchInputEvent
2. ViewRootImpl对事件的派发(InputStage)
2.1 ViewRootImpl.java dispatchInputEvent/enqueueInputEvent
2.2 InputStage.deliver
2.3 各个InputStage
2.4 InputStage开始分发事件 dispatchTouchEvent
3. Activity ViewGroup View的事件分发 dispatchTouchEvent和 onTouchEvent
3.1 View ViewGroup DecorView 继承关系
3.2 DecorView dispatchTouchEvent
3.3 Activity dispatchTouchEvent
3.4 ViewGroup dispatchTouchEvent
3.5 View dispatchTouchEvent
//事件详细信息,action表示事件类型,x,y表示事件发生的位置,deviceId是硬件设备的id值
EventTest: MainActivity dispatchTouchEvent: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=408.94913, y[0]=416.38184, toolType[0]=TOOL_TYPE_MOUSE, buttonState=BUTTON_PRIMARY, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=498914, downTime=498914, deviceId=13, source=0x2002 }
System.err: java.lang.Exception: EventTest2
System.err: at .*********************.MainActivity.dispatchTouchEvent(MainActivity.java:68)
System.err: at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:71)
System.err: at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:434)
System.err: at android.view.View.dispatchPointerEvent(View.java:12029)
System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4834)
//在onProcess方法中,进行事件类型的判断,然后根据不同的事件类型调用不同的处理方法
System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4644)
//在deliver中完成事件处理之后,调用finishInputEvent给输入系统一个反馈;
System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4176)
System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4229)
System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4195)
System.err: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4322)
System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4203)
System.err: at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4379)
System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4176)
System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4229)
System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4195)
System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4203)
System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4176) //1.5 InputStage.deliver()
System.err: at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6707)
System.err: at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6681)
System.err: at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6642) //1.4
System.err: at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6810) //调用到集成抽象类InputEventReceiver里面的WindowInputEventReceiver
//事件由native层正式进入到Java层
System.err: at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:187) //1.3 InputDiapatcher seedmsg后,fd触发handEvent调用到 dispatchInputEvent
System.err: at android.os.MessageQueue.nativePollOnce(Native Method) //1.1 handleEvent回调处理
System.err: at android.os.MessageQueue.next(MessageQueue.java:325)
System.err: at android.os.Looper.loop(Looper.java:142)
System.err: at android.app.ActivityThread.main(ActivityThread.java:6627)
System.err: at java.lang.reflect.Method.invoke(Native Method)
System.err: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
写一个简单的例子,验证下。选择一个View,重写其onTouchEvent方法,然后通过dumpStack方法来打印出当前线程的调用栈信息。
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, "onTouchEvent, ev=" + event.getAction());
Thread.dumpStack();
return true;
}
06-22 13:25:21.368 7365 7365 D FrameLayoutEx: onTouchEvent, ev=0
06-22 13:25:21.368 7365 7365 W System.err: java.lang.Throwable: stack dump
06-22 13:25:21.368 7365 7365 W System.err: at java.lang.Thread.dumpStack(Thread.java:490)
06-22 13:25:21.368 7365 7365 W System.err: at com.ryg.reveallayout.ui.FrameLayoutEx.onTouchEvent(FrameLayoutEx.java:27)
06-22 13:25:21.368 7365 7365 W System.err: at android.view.View.dispatchTouchEvent(View.java:9294)
06-22 13:25:21.368 7365 7365 W System.err: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2547)
06-22 13:25:21.368 7365 7365 W System.err: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2240)
06-22 13:25:21.368 7365 7365 W System.err: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
06-22 13:25:21.369 7365 7365 W System.err: at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403)
06-22 13:25:21.369 7365 7365 W System.err: at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737)
06-22 13:25:21.369 7365 7365 W System.err: at android.app.Activity.dispatchTouchEvent(Activity.java:2765)
06-22 13:25:21.369 7365 7365 W System.err: at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.View.dispatchPointerEvent(View.java:9514)
06-22 13:25:21.369 7365 7365 W System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4230)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4096)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
06-22 13:25:21.370 7365 7365 W System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
06-22 13:25:21.371 7365 7365 W System.err: at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5922)
06-22 13:25:21.371 7365 7365 W System.err: at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5896)
06-22 13:25:21.371 7365 7365 W System.err: at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5857)
06-22 13:25:21.371 7365 7365 W System.err: at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6025)
06-22 13:25:21.371 7365 7365 W System.err: at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
06-22 13:25:21.371 7365 7365 W System.err: at android.os.MessageQueue.nativePollOnce(Native Method)
06-22 13:25:21.371 7365 7365 W System.err: at android.os.MessageQueue.next(MessageQueue.java:323)
06-22 13:25:21.371 7365 7365 W System.err: at android.os.Looper.loop(Looper.java:135)
06-22 13:25:21.371 7365 7365 W System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
06-22 13:25:21.371 7365 7365 W System.err: at java.lang.reflect.Method.invoke(Native Method)
06-22 13:25:21.371 7365 7365 W System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
06-22 13:25:21.371 7365 7365 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit
onTouchEvent如下
09-05 09:28:07.840 7883 7883 W System.err: java.lang.Exception: Stack trace
09-05 09:28:07.840 7883 7883 W System.err: at java.lang.Thread.dumpStack(Thread.java:1348)
09-05 09:28:07.840 7883 7883 W System.err: at com.tsp.notification.MainActivity.onTouchEvent(MainActivity.java:86)
09-05 09:28:07.840 7883 7883 W System.err: at android.app.Activity.dispatchTouchEvent(Activity.java:3404)
09-05 09:28:07.840 7883 7883 W System.err: at com.tsp.notification.MainActivity.dispatchTouchEvent(MainActivity.java:81)
09-05 09:28:07.840 7883 7883 W System.err: at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
09-05 09:28:07.840 7883 7883 W System.err: at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:398)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.View.dispatchPointerEvent(View.java:12752)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5113)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4916)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4433)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4486)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4452)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4592)
09-05 09:28:07.840 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4460)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4649)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4433)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4486)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4452)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4460)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4433)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7099)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7068)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7029)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7202)
09-05 09:28:07.841 7883 7883 W System.err: at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
09-05 09:28:07.841 7883 7883 W System.err: at android.os.MessageQueue.nativePollOnce(Native Method)
09-05 09:28:07.841 7883 7883 W System.err: at android.os.MessageQueue.next(MessageQueue.java:326)
09-05 09:28:07.841 7883 7883 W System.err: at android.os.Looper.loop(Looper.java:160)
第一部分内容可参考前面ViewRootImpl的input内容
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); //consumeEvents 消耗事件
return status == OK || status == NO_MEMORY ? 1 : 0;
}
...
}
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
bool skipCallbacks = false;
for (;;) {
...
if (inputEventObj) {
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj, //gInputEventReceiverClassInfo.dispatchInputEvent
displayId);
...
}
}
}
private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event, displayId);
}
@frameworks/base/core/java/android/view/ViewRootImpl.java
final class WindowInputEventReceiver extends InputEventReceiver {
public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
}
@Override
public void onInputEvent(InputEvent event, int displayId) {
enqueueInputEvent(event, this, 0, true);
}
void enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately) {
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
QueuedInputEvent last = mPendingInputEventTail;
if (processImmediately) {
doProcessInputEvents();
} else {
scheduleProcessInputEvents();
}
}
void doProcessInputEvents() {
while (mPendingInputEventHead != null) {
QueuedInputEvent q = mPendingInputEventHead;
mPendingInputEventHead = q.mNext;
q.mNext = null;
deliverInputEvent(q);
}
}
//调用InputStage的各个方法deliver, 处理完事件后就会finishInputEvent来完成事件分发操作
private void deliverInputEvent(QueuedInputEvent q) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
}
InputStage stage;
if (stage != null) {
stage.deliver(q);
} else {
finishInputEvent(q);
}
}
mSyntheticInputStage = new SyntheticInputStage();
InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage);
InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,
"aq:native-post-ime:" + counterSuffix);
InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);
InputStage imeStage = new ImeInputStage(earlyPostImeStage,
"aq:ime:" + counterSuffix);
InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage);
InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage,
构造了7个InputStage实现类,
那么Activity和View的事件处理主要对应的InputStage是ViewPostImeInputStage。
//InputStage.deliver完之后,就会next到其他inputStage处理,这里到View的ViewPostImeInputStage来处理
System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4644)
System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4176)
System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4229)
System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4195)
System.err: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4322)
System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4203)
System.err: at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4379)
System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4176)
System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4229)
System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4195)
System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4203)
System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4176)
abstract class InputStage {
public final void deliver(QueuedInputEvent q) {
if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) {
forward(q);
} else if (shouldDropInputEvent(q)) {
finish(q, false);
} else {
apply(q, onProcess(q));
}
}
protected void onDeliverToNext(QueuedInputEvent q) {
if (DEBUG_INPUT_STAGES) {
Log.v(mTag, "Done with " + getClass().getSimpleName() + ". " + q);
}
if (mNext != null) {
mNext.deliver(q); //next deliver()
} else {
finishInputEvent(q);
}
}
final class ViewPostImeInputStage extends InputStage {
public ViewPostImeInputStage(InputStage next) {
super(next);
}
@Override
protected int onProcess(QueuedInputEvent q) {
if (q.mEvent instanceof KeyEvent) {
return processKeyEvent(q);
} else {
final int source = q.mEvent.getSource();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
return processPointerEvent(q); //processPointerEvent
} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
return processTrackballEvent(q);
} else {
return processGenericMotionEvent(q);
}
}
}
private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
mAttachInfo.mUnbufferedDispatchRequested = false;
mAttachInfo.mHandlingPointerEvent = true;
boolean handled = mView.dispatchPointerEvent(event); //mView继承关系调用
int action = event.getActionMasked();
...
return handled ? FINISH_HANDLED : FORWARD;
}
//会调用到DecorView dispatchTouchEvent
System.err: at .*********************.MainActivity.dispatchTouchEvent(MainActivity.java:68)
System.err: at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:71)
System.err: at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:434)
System.err: at android.view.View.dispatchPointerEvent(View.java:12029)
System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4834)
InputEvent有2个子类:KeyEvent和MotionEvent,其中KeyEvent表示键盘事件,而MotionEvent表示点击事件。
//View继承关系如下
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker{...}
public class FrameLayout extends ViewGroup {...}
public abstract class ViewGroup extends View implements ViewParent, ViewManager{..}
接着上面mView.dispatchPointerEvent(event)分析
@frameworks/base/core/java/android/view/View.java
public final boolean dispatchPointerEvent(MotionEvent event) {
if (event.isTouchEvent()) {
return dispatchTouchEvent(event);
} else {
return dispatchGenericMotionEvent(event);
}
}
根据mView继承调用
//先是子类 DecorView
@frameworks/base/core/java/com/android/internal/policy/DecorView.java
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Window.Callback cb = mWindow.getCallback();
return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
}
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback, //继承 Window.Callback
{
//调用Activity dispatchTouchEvent,可见先调用各个DispatchTouchEvent,最后才调用onTouchEvent,因此最早 dispatchTouchEvent,应用最晚 onTouchEvent
@Activity.java
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
//会调用到
@frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
@frameworks/base/core/java/com/android/internal/policy/DecorView.java
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker{...}
public class FrameLayout extends ViewGroup {...}
public abstract class ViewGroup extends View implements ViewParent, ViewManager{..}
//进入ViewGroup
@frameworks/base/core/java/android/view/ViewGroup.java
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
...
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
}
...
if (mFirstTouchTarget == null) {
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
} else {
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
}
return handled;
}
//调用View dispatchTouchEvent
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
final boolean handled;
...
// Perform any necessary transformations and dispatch.
if (child == null) {
handled = super.dispatchTouchEvent(transformedEvent);
} else {
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
transformedEvent.offsetLocation(offsetX, offsetY);
if (! child.hasIdentityMatrix()) {
transformedEvent.transform(child.getInverseMatrix());
}
handled = child.dispatchTouchEvent(transformedEvent);
}
}
@View.java
public boolean dispatchTouchEvent(MotionEvent event) {
if (onFilterTouchEventForSecurity(event)) {
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
result = true;
}
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) { //mOnTouchListener存在就会返回并且拦截事件,就不会走下面的 onTouchEvent,这样应用就可以处理
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
return result;
}