基于Android 9 分析
框架层可见的点击事件从哪里来? 所有的事件都是由InputEventReceiver 先接受再分发出来的,
1 2 3 4 5 6   @SuppressWarnings ("unused" )private  void  dispatchInputEvent (int  seq, InputEvent event, int  displayId)      mSeqMap.put(event.getSequenceNumber(), seq);     onInputEvent(event, displayId); } 
那native code 又是怎么才会调上来的呢? 那就是在 InputEventReceiver 初始化的时候,需要注册。就是在 nativeInit 方法里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21     public  InputEventReceiver (InputChannel inputChannel, Looper looper)           if  (inputChannel == null ) {             throw  new  IllegalArgumentException("inputChannel must not be null" );         }         if  (looper == null ) {             throw  new  IllegalArgumentException("looper must not be null" );         }         mInputChannel = inputChannel;         mMessageQueue = looper.getQueue();         mReceiverPtr = nativeInit(new  WeakReference<InputEventReceiver>(this ),                 inputChannel, mMessageQueue);         mCloseGuard.open("dispose" );     } 
InputChannel
An input channel specifies the file descriptors used to send input events to a window in another process.  It is Parcelable so that it can be sent to the process that is to receive events. Only one thread should be reading from an InputChannel at a time. 
输入通道指定用于在另一个进程中将输入事件发送到窗口的文件描述符。 它是Parcelable,因此可以将其发送到要接收事件的进程。 一次只能一个线程从InputChannel读取。 
 
1 2 private  static  native  long  nativeInit (WeakReference<InputEventReceiver> receiver,            InputChannel inputChannel, MessageQueue messageQueue) 
在我们启动App的时候,最先由AMS跨进程传输的一个ClientTransaction,客户端进程ApplicationThread接收,然后发送到主线程ActivityThread,最后由TransactionExecutor统一解析。AMS封装并传输ClientTransaction,统一接口;客户端进程接收ClientTransaction并使用TransactionExecutor解析AMS的请求,再根据ActivityLifecycleItem执行不同的代码。Activity的生命周期就是 transaction.getLifecycleStateRequest() 获取的,然后再执行响应的生命周期回调。
调用栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <init>(InputChannel, Looper):60 , InputEventReceiver (android.view)<init>(ViewRootImpl, InputChannel, Looper):7190 ,  ViewRootImpl$WindowInputEventReceiver (android.view) setView(View, WindowManager$LayoutParams, View):847 ,  ViewRootImpl (android.view) addView(View, ViewGroup$LayoutParams, Display, Window):356 , WindowManagerGlobal (android.view) addView(View, ViewGroup$LayoutParams):93 , WindowManagerImpl (android.view) handleResumeActivity(IBinder, boolean , boolean , String):3868 , ActivityThread (android.app) execute(ClientTransactionHandler, IBinder,PendingTransactionActions):51 , ResumeActivityItem (android.app.servertransaction) executeLifecycleState(ClientTransaction):145 ,  TransactionExecutor (android.app.servertransaction) execute(ClientTransaction):70 , TransactionExecutor (android.app.servertransaction) handleMessage(Message):1808 , ActivityThread$H (android.app) dispatchMessage(Message):106 , Handler (android.os) loop():193 , Looper (android.os) main(String[]):6669 , ActivityThread (android.app) invoke(Object, Object[]):-1 , Method (java.lang.reflect) run():493 , RuntimeInit$MethodAndArgsCaller (com.android.internal.os) main(String[]):858 , ZygoteInit (com.android.internal.os) 
我们可以看到 在 android.view.ViewRootImpl#setView当中调用了,这个looper就是主线程的looepr了。这个InputChannel 实际上指向我们自己写的MainActivity (client)
1 2 mInputEventReceiver = new  WindowInputEventReceiver(mInputChannel,                            Looper.myLooper()); 
再来看一 nativeInit 又做了什么呢? 在NativeInputEventReceiver的nativeInit方法中,创建了NativeInputEventReceiver对象,并调用它的initialize方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 static  jint nativeInit (JNIEnv* env, jclass clazz, jobject receiverWeak,         jobject inputChannelObj, jobject messageQueueObj)      ...          sp<NativeInputEventReceiver> receiver = new  NativeInputEventReceiver(env,             receiverWeak, inputChannel, messageQueue);          status_t  status = receiver->initialize();     ... } status_t  NativeInputEventReceiver::initialize ()      setFdEvents(ALOOPER_EVENT_INPUT);     return  OK; } 
mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL); 
实际上就把JAVA层的Looper关联ALOOPER_EVENT_INPUT 
 
1 2 3 4 5 6 7 8 9 10 11 void  NativeInputEventReceiver::setFdEvents (int  events)      if  (mFdEvents != events) {         mFdEvents = events;         int  fd = mInputConsumer.getChannel()->getFd();         if  (events) {             mMessageQueue->getLooper()->addFd(fd, 0 , events, this , NULL );         } else  {             mMessageQueue->getLooper()->removeFd(fd);         }     } } 
fd,fd即inputChannel的socket fd,Looper会侦测该fd的状态 
events,即传入的ALOOPER_EVENT_INPUT,只有fd的状态是INPUT的时候才会触发调用LooperCallback中的handleEvent方法 
this,即NativeInputEventReceiver,当fd状态为Input时,NativeInputEventReceiver中的handleEvent方法会被调用 
 
在consumeEvents内,我们能看到调用了InputConsume::consume来接收InputDispatcher发送过来的事件
1 2 3 4 5 6 7 status_t  NativeInputEventReceiver::consumeEvents (JNIEnv* env,         bool  consumeBatches, nsecs_t  frameTime, bool * outConsumedBatch)      for  (;;) {         status_t  status = mInputConsumer.consume(&mInputEventFactory,                 consumeBatches, frameTime, &seq, &inputEvent);         } } 
最终回调到 java 层的 InputEventReceiver#dispatchInputEvent 。
1 2 env->CallVoidMethod(receiverObj.get (),        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); 
通过上述的JNI调用,会调用到WindowInputEventReceiver的dispatchInputEvent方法,不过由于WindowInputEventReceiver并没有自己实现这个方法,因此会调用父类InputEventReceiver::dispatchInputEvent,内部会真正调用到android.view.ViewRootImpl.WindowInputEventReceiver#onInputEvent
接下来就是JAVA层,一层层分发事件了
android.view.ViewRootImpl.WindowInputEventReceiver#onInputEvent
1 2 3 public  void  onInputEvent (InputEvent event, int  displayId)              enqueueInputEvent(event, this , 0 , true );         } 
android.view.ViewRootImpl#enqueueInputEvent(android.view.InputEvent, android.view.InputEventReceiver, int, boolean)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void  enqueueInputEvent (InputEvent event,             InputEventReceiver receiver, int  flags, boolean  processImmediately)          adjustInputEventForCompatibility(event);                  QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);         QueuedInputEvent last = mPendingInputEventTail;                           if  (last == null ) {             mPendingInputEventHead = q;             mPendingInputEventTail = q;         } else  {             last.mNext = q;             mPendingInputEventTail = q;         }                  mPendingInputEventCount += 1 ;                  Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName,                 mPendingInputEventCount);                  if  (processImmediately) {             doProcessInputEvents();         } else  {                                       scheduleProcessInputEvents();         }     } 
从 enqueueInputEvent(event, this, 0, true) 看 ,这里的事件是processImmediately = true的,所以进一步再追一下  doProcessInputEvents()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 void  doProcessInputEvents ()                         while  (mPendingInputEventHead != null ) {                                    QueuedInputEvent q = mPendingInputEventHead;            mPendingInputEventHead = q.mNext;            if  (mPendingInputEventHead == null ) {                mPendingInputEventTail = null ;            }            q.mNext = null ;                        mPendingInputEventCount -= 1 ;                                    Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName,                    mPendingInputEventCount);            long  eventTime = q.mEvent.getEventTimeNano();            long  oldestEventTime = eventTime;            if  (q.mEvent instanceof  MotionEvent) {                MotionEvent me = (MotionEvent)q.mEvent;                if  (me.getHistorySize() > 0 ) {                    oldestEventTime = me.getHistoricalEventTimeNano(0 );                }            }            mChoreographer.mFrameInfo.updateInputEventTime(eventTime, oldestEventTime);                        deliverInputEvent(q);        }                                        if  (mProcessInputEventsScheduled) {            mProcessInputEventsScheduled = false ;            mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);        }    } 
接下来再继续追一下 android.view.ViewRootImpl#deliverInputEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  private  void  deliverInputEvent (QueuedInputEvent q)            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent" ,q.mEvent.getSequenceNumber());                    if  (mInputEventConsistencyVerifier != null ) {         mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0 );     }     InputStage stage;     if  (q.shouldSendToSynthesizer()) {         stage = mSyntheticInputStage;     } else  {         stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;     }     if  (q.mEvent instanceof  KeyEvent) {         mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);     }           if  (stage != null ) {         handleWindowFocusChanged();         stage.deliver(q);     } else  {         finishInputEvent(q);     } } 
deliverInputEvent先判断将事件派发到那个InputStage,然后调用该InputState的deliver方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  void  setView (View view, WindowManager.LayoutParams attrs, View panelParentView)      ...     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,             "aq:native-pre-ime:"  + counterSuffix);     mFirstInputStage = nativePreImeStage;     mFirstPostImeInputStage = earlyPostImeStage;     ... } 
InputStage 是在setView()的时候创建的,也就是在Activity的onResume()
通过一路的 forward deliver ,最后走到apply 的 onProcess 方法中去。也就是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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);              } else  if  ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0 ) {                  return  processTrackballEvent(q);              } else  {                  return  processGenericMotionEvent(q);              }          }      } 
那么再来看下一
android.view.ViewRootImpl.ViewPostImeInputStage#processPointerEvent 里面又是怎么发的? 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private  int  processPointerEvent (QueuedInputEvent q)         final  MotionEvent event = (MotionEvent)q.mEvent;        mAttachInfo.mUnbufferedDispatchRequested = false ;        mAttachInfo.mHandlingPointerEvent = true ;                                        boolean  handled = mView.dispatchPointerEvent(event);        maybeUpdatePointerIcon(event);        maybeUpdateTooltip(event);        mAttachInfo.mHandlingPointerEvent = false ;        if  (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) {            mUnbufferedInputDispatch = true ;            if  (mConsumeBatchedInputScheduled) {                scheduleConsumeBatchedInputImmediately();            }        }        return  handled ? FINISH_HANDLED : FORWARD;    } 
当调用到 DecorView 的 dispatchPointerEvent ,实际上是  android.view.View#dispatchPointerEvent ,接下来的问题实际上就是 view的事件分发了?
1 2 3 4 5 6 7 8 9  public  final  boolean  dispatchPointerEvent (MotionEvent event)                 if  (event.isTouchEvent()) {         return  dispatchTouchEvent(event);     } else  {         return  dispatchGenericMotionEvent(event);     } } 
转接到
com.android.internal.policy.DecorView#dispatchTouchEvent 
 
1 2 3 4 5 6 7 8 9 public  boolean  dispatchTouchEvent (MotionEvent ev)                     final  Window.Callback cb = mWindow.getCallback();          return  cb != null  && !mWindow.isDestroyed() && mFeatureId < 0              ? cb.dispatchTouchEvent(ev) : super .dispatchTouchEvent(ev); } 
最后cb.dispatchTouchEvent(ev)  就相当于 走入到了
android.app.-Activity#dispatchTouchEvent 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14   public  boolean  dispatchTouchEvent (MotionEvent ev)       if  (ev.getAction() == MotionEvent.ACTION_DOWN) {         onUserInteraction();     }                    if  (getWindow().superDispatchTouchEvent(ev)) {         return  true ;     }          return  onTouchEvent(ev); } 
Activity 的 getWindow() 就是 android.app.Activity#attach中的mWindow ,也就是 PhoneWindow。
com.android.internal.policy.PhoneWindow#superDispatchTouchEvent 
 
1 2 3 4 5  @Override  public  boolean  superDispatchTouchEvent (MotionEvent event)           return  mDecor.superDispatchTouchEvent(event); } 
从上面的标记1,2,3 可以看到,首先事件从 android.view.ViewRootImpl.ViewPostImeInputStage#processPointerEvent 发到 DecorView ,DecorView 再分发事件的时候,通过 Window 获取callback 拿到 Activity ,转交给Activity 去发送,但是Activity又通过 getWindow,又把事件转交给Window ,Window 最后又通过mDecor.superDispatchTouchEvent(event) 转交给 了DecorView。搞半天?最后还是回到 android.view.ViewRootImpl.ViewPostImeInputStage#processPointerEvent 的 mView.dispatchPointerEvent(event)中? 
显然不是 第一次调用的是 DecorView.dispatchPointerEvent(event) ,第二次回到 DecorView是调用的 DecorView.superDispatchTouchEvent(event);也就调用到 DecorView 的父类 DispatchTouchEvent ,最后也就是 android.view.ViewGroup#dispatchTouchEvent的了。
一小段调用栈
1 2 3 4 5 6 7 8 9 --- dispatchTouchEvent(MotionEvent):2543 , ViewGroup (android.view) superDispatchTouchEvent(MotionEvent):440 , DecorView (com.android.internal.policy) superDispatchTouchEvent(MotionEvent):1830 , PhoneWindow (com.android.internal.policy) dispatchTouchEvent(MotionEvent):3400 , Activity (android.app) dispatchTouchEvent(MotionEvent):398 , DecorView (com.android.internal.policy) dispatchPointerEvent(MotionEvent):12752 , View (android.view) processPointerEvent(ViewRootImpl$QueuedInputEvent):5106 ,、 --- 
为什么在InputStage.processPointerEvent()中不直接把事件传递给Activity,而是这样来回绕一圈。这样DecorView -> Activity -> PhoneWindow -> DecorView的来回绕一圈不是很折腾吗?
首先,为了解耦,ViewRootImpl并不知道有Activity这种东西存在!不知道!它只是持有了DecorView。所以,想要直接把触摸事件送到Activity.dispatchTouchEvent() 是不行的。
那么,既然触摸事件已经到了Activity.dispatchTouchEvent()中了,为什么不直接分发给DecorView ,而是要通过PhoneWindow 来间接发送呢?因为Activity 不知道有DecorView 这种奇怪的东西存在啊!不知道!但是,Activity持有PhoneWindow ,而PhoneWindow当然知道自己的窗口里有些什么了,所以能够把事件派发给DecorView 。你看,在Android中,Activity并不知道自己的Window中有些什么,这样耦合性就很低了。我们换一个Window试试?不管Window里面的内容如何,只要Window任然符合Activity制定的标准,那么它就能在Activity中很好的工作。这就是解耦所带来的扩展性的好处。
作者:CoorChicehttps://www.jianshu.com/p/b7cef3b3e703 
ViewGroup 的事件分发流程? 首先分清楚 3个方法
dispatchTouchEvent() 分发器,决定事件怎么分发,会先询问onInterceptTouchEvent(),如果拦截了 进一步到 自己的 onTouchEvent() 中去。如果没有拦截,转发到子view的dispatchTouchEvent() 
onInterceptTouchEvent() 拦截器 是ViewGroup特有的方法,可以判断和拦截要不要将事件下发到子view去处理。 
onTouchEvent() 处理器。最后的一个子view 收到事件将会直接由【分发器】分发到【处理器】中。如果处理了返回true,如果不处理返回false,那么事件将传递到它的父级的【处理器】中。 
 
不管个层级的【处理器】,如果处理事件返回true,一次触摸事件就结束了。如果不处理事件,返回false,就是事件还没有被消费,就会传送到上一级的【处理器】中。最终,如果DecorView的【处理器】也不打算处理事件,那么事件将会被发送到Activity的【处理器】中处理。
说白了,就是先交给子view优先消费,消费不了,返回了,我再消费。
那么ViewGroup dispatchTouchEvent()又是怎么把事件发到child view中去的呢? 
android.view.ViewGroup#dispatchTouchEvent 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 final  ArrayList<View> preorderedList = buildTouchDispatchChildList();final  boolean  customOrder = preorderedList == null         && isChildrenDrawingOrderEnabled(); final  View[] children = mChildren;for  (int  i = childrenCount - 1 ; i >= 0 ; i--) {    final  int  childIndex = getAndVerifyPreorderedIndex(             childrenCount, i, customOrder);     final  View child = getAndVerifyPreorderedView(             preorderedList, children, childIndex);                         if  (childWithAccessibilityFocus != null ) {         if  (childWithAccessibilityFocus != child) {             continue ;         }         childWithAccessibilityFocus = null ;         i = childrenCount - 1 ;     }         if  (!canViewReceivePointerEvents(child)             || !isTransformedTouchPointInView(x, y, child, null )) {         ev.setTargetAccessibilityFocus(false );         continue ;     } 
最后再子view的 android.view.View#onTouchEvent中,包装成一个 mPerformClick ,最后通过  mHandler.post(action) 把这个 action 发到 主线程的looper 里面去处理了,然后looepr 处理消息,调用action ,就是我们set的OnClickListener里面去了。
android.os.Handler#dispatchMessage 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  void  dispatchMessage (Message msg)                if  (msg.callback != null ) {         handleCallback(msg);     } else  {         if  (mCallback != null ) {             if  (mCallback.handleMessage(msg)) {                 return ;             }         }         handleMessage(msg);     } } 
最后 调到 message.callback.run(); 
然后  在run() 调用 performClick() 中的 mOnClickListener.onClick(this); 
 
最后我们 就开始我们的OnClick 逻辑了
总结 最后一张大图 
感谢 [Android] 输入系统(二)] https://www.cnblogs.com/TaigaCon/p/4750349.html 
作者:CoorChicehttps://www.jianshu.com/p/b7cef3b3e703