之前在了解touch事件的时候,都是从activity->phoneWindow->decoreVoew->content部分的view事件分发,而不知道底层是如何传递给view的,该篇文章就是介绍,底层是如何将事件传递给应用层的。下面先把traceView的截图列出来:
当屏幕收到触摸事件后,底层会给主线程的消息队列中插入一条消息,然后唤醒上层,上层的接收端是NativeInputEventReceriver的handleEvent:
接着调用了consumeEvents方法:
|
|
可以看到上面通过register_android_view_InputEventReceiver方法的注册,将gInputEventReceiverClassInfo
指向了java层的android/view/InputEventReceiver
。而在consumeEvents中通过env->CallVoidMethod调用jni到了android/view/InputEventReceiver
的dispatchInputEvent方法。接下来到了java层,直接看traceview
|
|
其实这个只是单次的点击事件,如果是多次触发点击,在viewrootimpl中会通过给Choreographer插入一条CALLBACK_INPUT的事件,这个根源也是在NativeInputEventReceiver的consumeEvents中触发了WindowInputEventReceiver的onBatchedInputEventPending,关键代码如下:
|
|
最终触发到ConsumeBatchedInputRunnable,最后会执行doProcessInputEvents->deliverInputEvent…,也就上单次点击的方法调用。从这里也可以看出,如果触摸事件积累很多的时候,会通过给Choreographer插入一条CALLBACK_INPUT的事件,然后等到下次vsync信号来的时候,才会去处理touch事件,减轻主线程的压力。通过此机制,Android 在保证输入响应的同时,最大限度减少 UI 线程的负载,优化整体流畅性。
多次触摸屏幕的时候trace文件