一、硬件层:事件的起源
MotionEvent 的生命周期始于用户触摸屏幕。
- 触控检测:屏幕的触控传感器检测到手指的触摸,并产生电信号。
- 驱动转换:硬件驱动将电信号转换为标准的 Linux 输入事件(
struct input_event),并将其写入设备节点/dev/input/eventX。
二、系统服务层:加工与分发
InputManagerService 负责从硬件读取事件,并将其加工、分发到正确的应用窗口。
InputReader:InputReader不断从设备节点中读取原始事件,并将其加工成MotionEvent对象。它负责处理多点触控、坐标转换等逻辑。InputDispatcher:InputDispatcher是事件分发的核心调度器。它根据MotionEvent的坐标和窗口层级(Z-Order),找到最顶层的应用窗口。然后,它通过 Binder IPC 将事件发送到目标应用的进程。
三、应用层:事件的最终处理
MotionEvent 到达应用进程后,会沿着一条由 Activity、ViewGroup 和 View 组成的责任链进行传递。
-
跨进程传递:事件到达应用进程后,首先被 Binder 线程接收。Binder 线程随后将事件封装成一个
Message,并将其发送到主线程的MessageQueue。 -
ViewRootImpl:主线程的Looper从MessageQueue中取出Message,并将其分发给ViewRootImpl。ViewRootImpl随后将事件传递给DecorView。 -
分发链:
DecorView是事件分发链的起点,它会调用dispatchTouchEvent()。事件会沿着视图树层层传递,直到找到一个愿意处理的View。 -
拦截与消费:
onInterceptTouchEvent():ViewGroup独有的方法,用于决定是否拦截事件。onTouchEvent():View和ViewGroup的方法,用于处理事件。其返回值(true或false)决定了事件是否被消费。
四、性能优化与风险点
MotionEvent 的传递过程对应用的流畅性至关重要。
- 主线程阻塞:如果主线程在处理
MotionEvent时被阻塞,InputDispatcher可能会因超时而触发 ANR。 - Vsync同步:
MotionEvent的处理需要与Vsync信号同步,以确保界面渲染和事件响应的节奏一致。 - 卡顿排查:使用 Systrace 或 Perfetto 等工具,可以直观地分析事件从硬件到应用的整个流程,从而定位性能瓶颈。