InputEventReceiver

  1. public InputEventReceiver(InputChannel inputChannel, Looper looper) {
  2. if (inputChannel == null) {
  3. throw new IllegalArgumentException("inputChannel must not be null");
  4. }
  5. if (looper == null) {
  6. throw new IllegalArgumentException("looper must not be null");
  7. }
  8. mInputChannel = inputChannel;
  9. mMessageQueue = looper.getQueue();
  10. //调用native代码初始化
  11. mReceiverPtr = nativeInit(new WeakReference<InputEventReceiver>(this),
  12. inputChannel, mMessageQueue);
  13. mCloseGuard.open("dispose");
  14. }

Androd事件 - 图1

InputEventReceiver nativeInit()方法的调用,这里系统 native 层就会将这个InputEventReceiver实例记录下来,每当有事件到达时就会通过inputChannel管道派发到这个实例上

  1. onInputEvent:7195, ViewRootImpl$WindowInputEventReceiver (android.view)
  2. dispatchInputEvent:186, InputEventReceiver (android.view) // // Called from native code.
  3. nativePollOnce:-1, MessageQueue (android.os) //底层事件上报
  4. next:326, MessageQueue (android.os)
  5. loop:160, Looper (android.os)
  6. main:6669, ActivityThread (android.app)
  7. invoke:-1, Method (java.lang.reflect)
  8. run:493, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
  9. main:858, ZygoteInit (com.android.internal.os)
  • 首先,当我们触摸屏幕时,通过Android消息机制,从Looper从MessageQueue中取出该事件,发送给WindowInputEventReceiver。
  • WindowInputEventReceiver是ViewRootImpl的内部类,通过enqueueInputEvent方法,将输入事件加入输入事件队列中,并进行处理和转发。
  • ViewPostImeInputStage收到输入事件,将事件传递给DecorView的dispatchPointerEvent()方法(是View的方法)
  • dispatchPointerEvent()方法通过DecorView中的dispatchTouchEvent()方法,调用了Activity的dispatchTouchEvent()方法
  1. sendMessageAtTime:4062, ViewRootImpl$ViewRootHandler (android.view)
  2. sendMessageDelayed:667, Handler (android.os)
  3. postDelayed:469, Handler (android.os)
  4. postDelayed:16707, View (android.view)
  5. onTouchEvent:13837, View (android.view)
  6. onTouchEvent:10064, TextView (android.widget)
  7. dispatchTouchEvent:12513, View (android.view)
  8. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  9. dispatchTouchEvent:2662, ViewGroup (android.view)
  10. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  11. dispatchTouchEvent:2662, ViewGroup (android.view)
  12. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  13. dispatchTouchEvent:2662, ViewGroup (android.view)
  14. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  15. dispatchTouchEvent:2662, ViewGroup (android.view)
  16. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  17. dispatchTouchEvent:2662, ViewGroup (android.view)
  18. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  19. dispatchTouchEvent:2662, ViewGroup (android.view)
  20. dispatchTransformedTouchEvent:3030, ViewGroup (android.view)
  21. dispatchTouchEvent:2662, ViewGroup (android.view)
  22. superDispatchTouchEvent:440, DecorView (com.android.internal.policy)
  23. superDispatchTouchEvent:1830, PhoneWindow (com.android.internal.policy)
  24. dispatchTouchEvent:3400, Activity (android.app)
  25. dispatchTouchEvent:69, i (a.b.o)
  26. dispatchTouchEvent:69, i (a.b.o)
  27. dispatchTouchEvent:398, DecorView (com.android.internal.policy)
  28. dispatchPointerEvent:12752, View (android.view)
  29. processPointerEvent:5106, ViewRootImpl$ViewPostImeInputStage (android.view)
  30. onProcess:4909, ViewRootImpl$ViewPostImeInputStage (android.view)
  31. deliver:4426, ViewRootImpl$InputStage (android.view)
  32. onDeliverToNext:4479, ViewRootImpl$InputStage (android.view)
  33. forward:4445, ViewRootImpl$InputStage (android.view)
  34. forward:4585, ViewRootImpl$AsyncInputStage (android.view)
  35. apply:4453, ViewRootImpl$InputStage (android.view)
  36. apply:4642, ViewRootImpl$AsyncInputStage (android.view)
  37. deliver:4426, ViewRootImpl$InputStage (android.view)
  38. onDeliverToNext:4479, ViewRootImpl$InputStage (android.view)
  39. forward:4445, ViewRootImpl$InputStage (android.view)
  40. apply:4453, ViewRootImpl$InputStage (android.view)
  41. deliver:4426, ViewRootImpl$InputStage (android.view)
  42. deliverInputEvent:7092, ViewRootImpl (android.view)
  43. doProcessInputEvents:7061, ViewRootImpl (android.view)
  44. enqueueInputEvent:7022, ViewRootImpl (android.view)//将输入事件加入输入事件队列中,并进行处理和转发
  45. onInputEvent:7195, ViewRootImpl$WindowInputEventReceiver (android.view)
  46. dispatchInputEvent:186, InputEventReceiver (android.view)//native层上报事件
  47. nativePollOnce:-1, MessageQueue (android.os)
  48. next:326, MessageQueue (android.os)
  49. loop:160, Looper (android.os)
  50. main:6669, ActivityThread (android.app)
  51. invoke:-1, Method (java.lang.reflect)
  52. run:493, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
  53. main:858, ZygoteInit (com.android.internal.os)

事件传递规则

Androd事件 - 图2

当Activity接受到点击事件后,会传递给Window再传递给DecorView,DecorView就是一个ViewGroup,他的dispatchTouchEvent就会被调用,如果这个ViewGroup的onInterceptTouchEvent方法返回true,就表示它要拦截事件,事件就会交给这个ViewGroup来处理;如果这个ViewGroup的onInterceptTouchEvent返回false,表示不拦截当前事件,这时,当前事件就会继续传递给它的子元素,子元素的dispatchTouchEvent方法就会被调用,如此反复直到事件被最终处理。(ViewGroup一般默认不拦截事件)

Androd事件 - 图3