事件在Android Framework层的完整流程

以下分析基于:android-28(Android 9.0)源码。

在MessageQueue中,有两个重要的方法:一个是enqueueMessage,负责将消息加入队列;一个是next,负责从消息队列中取出一个待处理的消息。

// android.os.MessageQueue
MessageQueue {
	boolean enqueueMessage(Message msg, long when) {
		// ...
	}
	
	Message next() {
		// ...
		for (;;) {
			// ...
            nativePollOnce(ptr, nextPollTimeoutMillis);
            // ...
        }
	}
}

在从消息队列中取出下一条消息时,会调用nativePollOnce方法,进入native层,在native中经过一系列处理,最终会回调到Framework层InputEventReceiver.java的dispatchInputEvent方法。

native中的处理及整个完整的过程,欢迎参考Gityuan的Input系统—事件处理全过程一文。

android.view.InputEventReceiver.java:

	// Called from native code.
    @SuppressWarnings("unused")
    private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
        mSeqMap.put(event.getSequenceNumber(), seq);
        onInputEvent(event, displayId);
    }

那在Framework中,具体是怎么传递事件的呢?这个时候就需要慢慢分析源码了。下面用图表示流程,具体代码以后有时间加上。

InputEventReceiver ViewRootImpl View DecorView Window.Callback PhoneWindow ViewGroup native调用处理... dispatchInputEvent $WindowInputEventReceiver:onInputEvent enqueueInputEvent doProcessInputEvents deliverInputEvent $InputStage: deliver() $ViewPostImeInputStage: onProcess() $ViewPostImeInputStage: processPointerEvent() dispatchPointerEvent dispatchTouchEvent Window.Callback 即 Activity或Dialog dispatchTouchEvent superDispatchTouchEvent superDispatchTouchEvent dispatchTouchEvent InputEventReceiver ViewRootImpl View DecorView Window.Callback PhoneWindow ViewGroup

Debug分析

如果怕自己看源码静态分析的时候跟着各种跳转被绕进去,这里分享一个小技巧:准备好手机或模拟器,我们新建一个空项目,gradle中的compileSdkVersion设置为和手机或模拟器系统版本一致,并通过Studio的SDK Manager下载好对应版本源码;只需要在MainActivity中放一个Button,在ViewGroup的dispatchTouchEvent方法中打上断点,然后Debug运行应用或运行后Attach,点击一下Button,就可以看到应用进入断点了,从Debugger窗口的方法调用栈,我们就能清晰的看到事件的整个传递过程了。点击调用栈中的方法,就能清楚的看到具体的调用位置了。
事件在Android Framework层的完整流程_第1张图片

你可能感兴趣的:(Android开发)