......
public boolean dispatchKeyEvent(KeyEvent event) {
// If any attached key listener a first crack at the event.
//noinspection SimplifiableIfStatement
......
if (mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
return true;
}
return event.dispatch(this, mAttachInfo != null
? mAttachInfo.mKeyDispatchState : null, this);
}
......
}
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
......
private OnKeyListener mOnKeyListener;
......
public boolean dispatchKeyEvent(KeyEvent event) {
// If any attached key listener a first crack at the event.
//noinspection SimplifiableIfStatement
......
if (mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
return true;
}
return event.dispatch(this, mAttachInfo != null
? mAttachInfo.mKeyDispatchState : null, this);
}
......
}
这个函数定义在文件frameworks/base/core/java/android/view/View.java中。
当View类的成员变量mOnKeyListener的值不等于null时,它所指向的一个OnKeyListener对象描述的是注册到当前正在处理的视图的一个键盘事件监听器。在这种情况下,如果当前正在处理的视图是处于启用状态的,即它的成员变量mViewFlags的ENABLED位等于1,那么参数event所描述的键盘事件就先分给该键盘事件监听器处理,这是通过调用View类的成员变量mOnKeyListener所指向的一个OnKeyListener对象的成员函数onKey来实现的。
注册到当前正在处理的视图的键盘事件监听器在处理完成参数event所描述的键盘事件之后,如果希望该键盘事件还能继续往下处理,那么View类的成员函数dispatchKeyEvent就会继续调用参数event所指向的一个KeyEvent对象的成员函数dispatch来处理该键盘事件。
接下来,我们就继续分析KeyEvent类的成员函数dispatch的实现,以便可以了解键盘事件在Activity组件窗口的分发过程。
Step 12. KeyEvent.dispatch
[java] view plaincopyprint?
public class KeyEvent extends InputEvent implements Parcelable {
......
public final boolean dispatch(Callback receiver, DispatcherState state,
Object target) {
switch (mAction) {
case ACTION_DOWN: {
......
boolean res = receiver.onKeyDown(mKeyCode, this);
......
return res;
}
case ACTION_UP:
......
return receiver.onKeyUp(mKeyCode, this);
case ACTION_MULTIPLE:
final int count = mRepeatCount;
final int code = mKeyCode;
if (receiver.onKeyMultiple(code, count, this)) {
return true;
}
......
return false;
}
return false;
}
......
}
public class KeyEvent extends InputEvent implements Parcelable {
......
public final boolean dispatch(Callback receiver, DispatcherState state,
Object target) {
switch (mAction) {
case ACTION_DOWN: {
......
boolean res = receiver.onKeyDown(mKeyCode, this);
......
return res;
}
case ACTION_UP:
......
return receiver.onKeyUp(mKeyCode, this);
case ACTION_MULTIPLE:
final int count = mRepeatCount;
final int code = mKeyCode;
if (receiver.onKeyMultiple(code, count, this)) {
return true;
}
......
return false;
}
return false;
}
......
}
这个函数定义在文件frameworks/base/core/java/android/view/KeyEvent.java中。
从前面的调用过程可以知道,参数receiver指向的是一个View对象所实现的一个KeyEvent.Callback接口,这个KeyEvent.Callback接口是用来接收当前正在处理的键盘事件。
KeyEvent类的成员变量mAction描述的的是当前正在处理的键盘事件的类型,当它的值等于ACTION_DOWN、ACTION_UP和ACTION_MULTIPLE的时候,KeyEvent类的成员函数dispatch就会分别调用参数receiver所指向的一个View对象的成员函数onKeyDown、onKeyUp和onKeyMultiple来接收当前正在处理的键盘事件。
假设当前正在处理的键盘事件是与按键按下相关的,即KeyEvent类的成员变量mAction的值等于ACTION_DOWN,那么接下来就会调用参数receiver所指向的一个View对象的成员函数onKeyDown来接收当前正在处理的键盘事件。
由于前面我们已经假设了当前获得焦点的是一个TextView控件,因此,参数receiver指向的实际上是一个TextView对象。TextView类重写了父类View的成员函数onKeyDown,因此,接下来KeyEvent类的成员函数dispatch就会调用TextView类的成员函数onKeyDown来接收当前正在处理的键盘事件。
原文转自:http://blog.csdn.net/luoshengyang/article/details/8636153