Android应用程序键盘(Keyboard)消息处理机制分析(21)
2011-10-24 00:59
549 查看
Step 30. ViewRoot.dispatchFinishedEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
public void dispatchFinishedEvent(int seq, boolean handled) {
Message msg = obtainMessage(FINISHED_EVENT);
msg.arg1 = seq;
msg.arg2 = handled ? 1 : 0;
sendMessage(msg);
}
......
}
和前面的Step 26一样,ViewRoot不是直接处理这个键盘事件,而是把它作为一个消息(FINISHED_EVENT)放在消息队列中去,最后,这个消息由ViewRoot的handleFinishedEvent函数来处理。 Step 31. ViewRoot.handleFinishedEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
void handleFinishedEvent(int seq, boolean handled) {
final KeyEvent event = (KeyEvent)retrievePendingEvent(seq);
......
if (event != null) {
final boolean sendDone = seq >= 0;
if (!handled) {
deliverKeyEventToViewHierarchy(event, sendDone);
return;
} else if (sendDone) {
......
} else {
......
}
}
}
......
}
如果InputMethodManager没有处理这个键盘事件,那么ViewRoot就会调用deliverKeyEventToViewHierarchy函数来把这个键盘事件分发给当前激活的Activity窗口来处理。
Step 32. ViewRoot.deliverKeyEventToViewHierarchy
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) {
try {
if (mView != null && mAdded) {
......
boolean keyHandled = mView.dispatchKeyEvent(event);
}
......
} finally {
if (sendDone) {
finishInputEvent();
}
}
}
......
}
这个函数首先会调用ViewRoot类的成员变量mView的dispatchKeyEvent来处理这个键盘事件,然后最调用ViewRoot类的finishInputEvent来处理手尾工作。
ViewRoot类的成员变量mView的类型为DecorView,它是由ActivityThread类第一次Resume当前的Activity窗口时创建的,具体可以参考ActivityThread类的handleResumeActivity成员函数,这里就不关注了。
Step 33. DecorView.dispatchKeyEvent
这个函数定义在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java文件中,它是PhoneWindow类的一个内部类:
public class PhoneWindow extends Window implements MenuBuilder.Callback {
......
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
......
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
......
final Callback cb = getCallback();
final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
: super.dispatchKeyEvent(event);
......
}
......
}
......
}
这里通过getCallback函数返回的是当前应用程序的激活的Activity窗口的Window.Callback接口,一般它不为NULL,因此,这个函数会调用Activity类的dispatchKeyEvent来处理这个键盘事件。
Step 34. Activity.dispatchKeyEvent
这个函数定义在frameworks/base/core/java/android/app/Activity.java文件中:
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
......
public boolean dispatchKeyEvent(KeyEvent event) {
......
View decor = mDecor;
if (decor == null) decor = win.getDecorView();
return event.dispatch(this, decor != null
? decor.getKeyDispatcherState() : null, this);
}
......
}
这里,Activity不是直接处理这个键盘事件,而是通过KeyEvent的dispatch转发一下。注意,KeyEvent的成中函数dispatch的第一个参数的类型是KeyEvent.Callback,而Activity实现了这个接口,因此,这里可以传this引用过去。
Step 35. KeyEvent.dispatch
这个函数定义在frameworks/base/core/java/android/view/KeyEvent.java文件中:
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;
}
......
}
这里就根据一个键是按下(ACTION_DOWN)、还是松开(ACTION_UP)或者是一个相同的键被多次按下和松开(ACTION_MULTIPLE)等不同事件类型来分别调用Activity的onKeyDown、onKeyUp和onKeyMultiple函数了。
Activity窗口处理完这个键盘事件后,层层返回,最后回到Step 32中,调用finishInputEvent事件来处理一些手尾工,下面我们将会看到这些手尾工是什么。
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
public void dispatchFinishedEvent(int seq, boolean handled) {
Message msg = obtainMessage(FINISHED_EVENT);
msg.arg1 = seq;
msg.arg2 = handled ? 1 : 0;
sendMessage(msg);
}
......
}
和前面的Step 26一样,ViewRoot不是直接处理这个键盘事件,而是把它作为一个消息(FINISHED_EVENT)放在消息队列中去,最后,这个消息由ViewRoot的handleFinishedEvent函数来处理。 Step 31. ViewRoot.handleFinishedEvent
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
void handleFinishedEvent(int seq, boolean handled) {
final KeyEvent event = (KeyEvent)retrievePendingEvent(seq);
......
if (event != null) {
final boolean sendDone = seq >= 0;
if (!handled) {
deliverKeyEventToViewHierarchy(event, sendDone);
return;
} else if (sendDone) {
......
} else {
......
}
}
}
......
}
如果InputMethodManager没有处理这个键盘事件,那么ViewRoot就会调用deliverKeyEventToViewHierarchy函数来把这个键盘事件分发给当前激活的Activity窗口来处理。
Step 32. ViewRoot.deliverKeyEventToViewHierarchy
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) {
try {
if (mView != null && mAdded) {
......
boolean keyHandled = mView.dispatchKeyEvent(event);
}
......
} finally {
if (sendDone) {
finishInputEvent();
}
}
}
......
}
这个函数首先会调用ViewRoot类的成员变量mView的dispatchKeyEvent来处理这个键盘事件,然后最调用ViewRoot类的finishInputEvent来处理手尾工作。
ViewRoot类的成员变量mView的类型为DecorView,它是由ActivityThread类第一次Resume当前的Activity窗口时创建的,具体可以参考ActivityThread类的handleResumeActivity成员函数,这里就不关注了。
Step 33. DecorView.dispatchKeyEvent
这个函数定义在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java文件中,它是PhoneWindow类的一个内部类:
public class PhoneWindow extends Window implements MenuBuilder.Callback {
......
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
......
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
......
final Callback cb = getCallback();
final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
: super.dispatchKeyEvent(event);
......
}
......
}
......
}
这里通过getCallback函数返回的是当前应用程序的激活的Activity窗口的Window.Callback接口,一般它不为NULL,因此,这个函数会调用Activity类的dispatchKeyEvent来处理这个键盘事件。
Step 34. Activity.dispatchKeyEvent
这个函数定义在frameworks/base/core/java/android/app/Activity.java文件中:
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
......
public boolean dispatchKeyEvent(KeyEvent event) {
......
View decor = mDecor;
if (decor == null) decor = win.getDecorView();
return event.dispatch(this, decor != null
? decor.getKeyDispatcherState() : null, this);
}
......
}
这里,Activity不是直接处理这个键盘事件,而是通过KeyEvent的dispatch转发一下。注意,KeyEvent的成中函数dispatch的第一个参数的类型是KeyEvent.Callback,而Activity实现了这个接口,因此,这里可以传this引用过去。
Step 35. KeyEvent.dispatch
这个函数定义在frameworks/base/core/java/android/view/KeyEvent.java文件中:
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;
}
......
}
这里就根据一个键是按下(ACTION_DOWN)、还是松开(ACTION_UP)或者是一个相同的键被多次按下和松开(ACTION_MULTIPLE)等不同事件类型来分别调用Activity的onKeyDown、onKeyUp和onKeyMultiple函数了。
Activity窗口处理完这个键盘事件后,层层返回,最后回到Step 32中,调用finishInputEvent事件来处理一些手尾工,下面我们将会看到这些手尾工是什么。
相关文章推荐
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(20)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(5)
- Android应用程序键盘(Keyboard)消息处理机制分析(22)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(6)
- Android应用程序键盘(Keyboard)消息处理机制分析(23)
- Android应用程序键盘(Keyboard)消息处理机制分析(7)
- Android应用程序键盘(Keyboard)消息处理机制分析(24)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(8)
- Android应用程序键盘(Keyboard)消息处理机制分析(25)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(9)
- Android应用程序键盘(Keyboard)消息处理机制分析(26)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(10)
- Android应用程序键盘(Keyboard)消息处理机制分析(27)
- Android应用程序键盘(Keyboard)消息处理机制分析(二)