final class SyntheticInputStage extends InputStage
final class NativePostImeInputStage extends AsyncInputStage
implements InputQueue.FinishedInputEventCallback
final class ViewPostImeInputStage extends InputStage
/** \frameworks\base\core\java\android\view\ViewRootImpl.java **/
abstract class InputStage {
private final InputStage mNext;
protected static final int FORWARD = 0;
protected static final int FINISH_HANDLED = 1;
protected static final int FINISH_NOT_HANDLED = 2;
/**
* Creates an input stage.
* @param next The next stage to which events should be forwarded.
*/
public InputStage(InputStage next) {
mNext = next;
}
/**
* 处理event
*/
public final void deliver(QueuedInputEvent q) {
// 有效的event传递给下一stage
if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) {
forward(q);
} else if (shouldDropInputEvent(q)) { // 应当被drop的Event
finish(q, false);
} else {
apply(q, onProcess(q));
}
}
/**
* 标记该event为finished,并传递给下一个stage
*/
protected void finish(QueuedInputEvent q, boolean handled) {
q.mFlags |= QueuedInputEvent.FLAG_FINISHED;
if (handled) {
q.mFlags |= QueuedInputEvent.FLAG_FINISHED_HANDLED;
}
forward(q);
}
/**
* 将event向前传递给下一个stage
*/
protected void forward(QueuedInputEvent q) {
onDeliverToNext(q);
}
/**
* 根据result code处理对应的event
* Applies a result code from {@link #onProcess} to the specified event.
*/
protected void apply(QueuedInputEvent q, int result) {
if (result == FORWARD) {
forward(q);
} else if (result == FINISH_HANDLED) {
finish(q, true);
} else if (result == FINISH_NOT_HANDLED) {
finish(q, false);
} else {
throw new IllegalArgumentException("Invalid result: " + result);
}
}
/**
* 一般继承类会Override该函数
* Called when an event is ready to be processed.
* @return A result code indicating how the event was handled.
*/
protected int onProcess(QueuedInputEvent q) {
return FORWARD;
}
/**
* 将event传递给下一stage
*/
protected void onDeliverToNext(QueuedInputEvent q) {
if (DEBUG_INPUT_STAGES) {
Log.v(TAG, "Done with " + getClass().getSimpleName() + ". " + q);
}
if (mNext != null) {
mNext.deliver(q);
} else {
// 调用ViewRootImpl的方法
finishInputEvent(q);
}
}
// 判断是否应该丢弃该Event
protected boolean shouldDropInputEvent(QueuedInputEvent q) {
if (mView == null || !mAdded) {
Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
return true;
} else if ((!mAttachInfo.mHasWindowFocus || mStopped)
&& !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
// 这里是一个focus事件,但当前该window已经不持有input focus,或者已经stopped.
// 该情况可能是该event来自于previous stage,但与此同时该window失去了焦点或者已经被停止
if (isTerminalInputEvent(q.mEvent)) {
// Don't drop terminal input events, however mark them as canceled.
q.mEvent.cancel();
Slog.w(TAG, "Cancelling event due to no window focus: " + q.mEvent);
return false;
}
// Drop non-terminal input events.
Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent);
return true;
}
return false;
}
void dump(String prefix, PrintWriter writer) {
if (mNext != null) {
mNext.dump(prefix, writer);
}
}
}
来重点看一下其继承类ViewPostInmInputStage:
1)ViewPostImeInputStage#onProgress:
/** \frameworks\base\core\java\android\view\ViewRootImpl.java **/
@Override
protected int onProcess(QueuedInputEvent q) {
if (q.mEvent instanceof KeyEvent) { // 如果是按键事件,processKeyEvent进行处理
return processKeyEvent(q);
} else {
// If delivering a new non-key event, make sure the window is
// now allowed to start updating.
handleDispatchDoneAnimating();
final int source = q.mEvent.getSource();
// 通过source即事件源来分类型进行处理
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);
}
}
}
当判断是 SOURCE_CLASS_POINTER类型的事件后,会调用processPointerEvent方法进行处理。
2)ViewPostImeInputStage#processPointEvent:
/** \frameworks\base\core\java\android\view\View.java **/
private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
mAttachInfo.mUnbufferedDispatchRequested = false;
// 此时ViewRootImpl会将事件的处理权移交给View树的根节点,调用dispatchPointerEvent函数
boolean handled = mView.dispatchPointerEvent(event);
if (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) {
mUnbufferedInputDispatch = true;
if (mConsumeBatchedInputScheduled) {
scheduleConsumeBatchedInputImmediately();
}
}
return handled ? FINISH_HANDLED : FORWARD;
}
ViewRootImpl负责将Event事件传递进来,并根据source的不同进行分类处理;进而将事件的控制权与处理权移交给View树的根View进行dispatchPointerEvent进行处理。
3)View#dispatchPointerEvent:
/** \frameworks\base\core\java\android\view\View.java **/
public final boolean dispatchPointerEvent(MotionEvent event) {
// 按照是否是TouchEvent进行分别处理
if (event.isTouchEvent()) {
return dispatchTouchEvent(event);
} else { // 如果不是调用GenericMotionEvent(Generic——一般的)
return dispatchGenericMotionEvent(event);
}
}
/** \frameworks\base\core\java\android\view\View.java **/
public boolean dispatchTouchEvent(MotionEvent event) {
......
// 根据安全策略对Touch Event进行过滤
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
// ListenerInfo中注册了众多的Listener
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
// 可以看到这里会首先调用TouchListener中的onTouch进行事件处理
result = true;
}
// 如果TouchListener中的onTouch返回结果为false的话,View中的onTouchEvent才会继续调用
if (!result && onTouchEvent(event)) {
result = true;
}
}
......
return result;
}
从上面可以看到onTouch与onTouchEvent之间的区别:
1>onTouch方法:
onTouch方法是View的 OnTouchListener借口中定义的方法。
当一个View绑定了OnTouchLister后,当有touch事件触发时,就会调用onTouch方法。
(当把手放到View上后,onTouch方法被一遍一遍地被调用)
2>onTouchEvent方法:
onTouchEvent方法是override 的Activity的方法。
重新了Activity的onTouchEvent方法后,当屏幕有touch事件时,此方法就会别调用。
(当把手放到Activity上时,onTouchEvent方法就会一遍一遍地被调用)
View 中存在onTouchEvent方法,在定义View的时候重写onTouchEvent可以进行事件处理。
3>touch事件的传递:
在一个Activity里面放一个TextView的实例tv,并且这个tv的属性设定为 fill_parent
在这种情况下,当手放到屏幕上的时候,首先会是tv响应touch事件,执行onTouch方法。
如果onTouch返回值为true,
表示这个