Android按键事件处理流程 -- KeyEvent

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android按键事件处理流程 -- KeyEvent

2014/6/24 13:18:58 xiaoweiz 程序员俱乐部我要评论(0)

刚接触Android开发的时候,对touch、key事件的处理总是一知半解,一会是Activity里的方法,一会是各种View

中的,自己始终不清楚到底哪个在先哪个在后,总之对整个处理流程没能很好的把握。

每次写这部分代码的时候都有些心虚,

因为我不是很清楚什么时候、以什么样的顺序被调用,大都是打下log看看,没问题就算ok了。但随着时间流逝,这种感觉一直

折磨着我。期间也在网上搜索了相关资料,但总感觉不是那么令人满意。自打开始研究Android源码起,这部分内容的分析早就

被列在我的TODO list上了。因为弄懂这部分处理逻辑对明明白白地写android程序实在是太重要了,所以今天我就带领大家看看

这部分的处理逻辑。touch事件的处理我将放在另一篇博客中介绍(相比KeyEvent,大体都一样,只是稍微复杂些)。

为了突出本文的重点,我们直接从事件被派发到View层次结构的根节点DecorView 开始分析,这里我们先来看看DecorView#

dispatchKeyEvent方法,代码如下:

@Override

public boolean dispatchKeyEvent(KeyEvent event) {

final int keyCode = event.getKeyCode();

final int action = event.getAction();

final boolean isDown = action == KeyEvent.ACTION_DOWN;

/// 1. 第一次down事件的时候,处理panel的快捷键

if (isDown && (event.getRepeatCount() == 0)) {

// First handle chording of panel key: if a panel key is held // but not released, try to execute a shortcut in it.

if ((mPanelChordingKey > 0) && (mPanelChordingKey != keyCode)) {

boolean handled = dispatchKeyShortcutEvent(event);

if (handled) {

return true;

}

}

// If a panel is open, perform a shortcut on it without the // chorded panel key

if ((mPreparedPanel != null) && mPreparedPanel.isOpen) { if (performPanelShortcut(mPreparedPanel, keyCode, event, 0)) {

return true;

}

}

}

/// 2. 这里是我们本文的重点,当window没destroy且其Callback 非空的话,交给其Callback处理

if (!isDestroyed()) { // Activity、Dialog都是Callback接口的实现

final Callback cb = getCallback(); // mFeatureId < 0 表示是application的DecorView,比如Activity、Dialog

final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event) // 派发给callback的方法

: super.dispatchKeyEvent(event); // 否则直接派发到ViewGroup#dispatchKeyEvent(View层次结构)

if (handled) {

return true; // 如果被上面的步骤处理了则直接返回true,不再往下传递

}

}

/// 3. 这是key事件的最后一步,如果到这一步还没处理掉,则派发到PhoneWindow对应的onKeyDown, onKeyUp方法

return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event)

: PhoneWindow.this.onKeyUp(mFeatureId,

event.getKeyCode(), event);

}

接下来我们按照这个派发顺序依次来看看相关方法的实现,这里先看看

Activity(Callback)的dispatchKeyEvent实现:

/**

* Called to process key events. You can override this to intercept all

* key events before they are dispatched to the window. Be sure to call

* this implementation for key events that should be handled normally. *

* @param event The key event.

*

* @return boolean Return true if this event was consumed.

*/

@Override

public boolean dispatchKeyEvent(KeyEvent event) {

/// 2.1. 回调接口,实际开发中用处不大,你感兴趣可以参看其方法doc onUserInteraction();

Window win = getWindow();

/// 2.2. 从这里事件的处理交给了与之相关的window对象,实质是派发到了view层次结构

if (win.superDispatchKeyEvent(event)) {

return true;

}

View decor = mDecor;

if (decor == null) decor = win.getDecorView();

/// 2.3. 到这里如果view层次结构没处理则交给KeyEvent本身的dispatch方法,Activity的各种回调方法会被触发

相关文档
最新文档