开局叠甲,可能理解有误,请大佬们斧正。
前面我们追到android_view_InputEventReceiver的consumeEvents()方法,
那么这个事件是怎么分发到View的?
//android_view_InputEventReceiver.cpp
consumeEvents(){
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.onBatchedInputEventPending,
mInputConsumer.getPendingBatchSource());
}
这里调用JNI会回调WindowInputEventReceiver 注意WindowInputEventReceiver 是继承了InputEventReceiver。
-->WindowInputEventReceiver.onBatchedInputEventPending()
-->consumeBatchedInputEvents(-1);
-->nativeConsumeBatchedInputEvents(mReceiverPtr, frameTimeNanos);
//再次回到android_view_InputEventReceiver.cpp
--> nativeConsumeBatchedInputEvents(){
status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos,
&consumedBatch);
}
--> env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
//再次调回InputEventReceiver,因为WindowInputEventReceiver没重载该方法
-->InputEventReceiver.dispatchInputEvent(){
//seq 很重要
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event);
}
//因为我们是 WindowInputEventReceiver
--> WindowInputEventReceiver.onInputEvent()
调用到这里onInputEvent()接下来调用链条如下
//ViewRootImpl
// enqueueInputEvent(event, this, 0, true);
--> enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately){
if (processImmediately) {
//走立马处理
doProcessInputEvents();
} else {
scheduleProcessInputEvents();
}
}
-->deliverInputEvent()
-->stage.deliver(q);
-->onProcess(q);
onProcess(q) 这里会依次走 EarlyPostImeInputStage/NativePostImeInputStage/ViewPostImeInputStage,
这是因为在setView()使用了责任链倒置模式。
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
//省略
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);
//省略
}
ViewPostImeInputStage的onProcess() 调用 processPointerEvent(q);
final class ViewPostImeInputStage extends InputStage {
public ViewPostImeInputStage(InputStage next) {
super(next);
}
@Override
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);
}
}
}
processPointerEvent(q)里面调用了mView.dispatchPointerEvent(event);将事件传递给了mView,我们知道其实这里的mView 是布局构建出来的,接下来就会走到我们常说的事件分发机制。
注意最后返回的是FINISH_HANDLED ,后面要用到的。
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;
}
到此 ,我们大体明白分发下来的事件是怎么从Nativie 到达了Java层,进入了我们常说的事件分发。下一步我们将看事件的销毁和ANR相关。