Android中按键消息的派发过程及源码分析(3)

如果拥有焦点的View没有处理该按键消息,则继续调用event.dispatch()函数:

/**       * Deliver this key event to a {@link Callback} interface.  If this is       * an ACTION_MULTIPLE event and it is not handled, then an attempt will       * be made to deliver a single normal event.       *        * @param receiver The Callback that will be given the event.       * @param state State information retained across events.       * @param target The target of the dispatch, for use in tracking.       *        * @return The return value from the Callback method that was called.       */       public final boolean dispatch(Callback receiver, DispatcherState state,               Object target) {           switch (mAction) {               case ACTION_DOWN: {                   mFlags &= ~FLAG_START_TRACKING;                   if (DEBUG) Log.v(TAG, "Key down to " + target + " in " + state                           + ": " + this);                   boolean res = receiver.onKeyDown(mKeyCode, this);                   if (state != null) {                       if (res && mRepeatCount == 0 && (mFlags&FLAG_START_TRACKING) != 0) {                           if (DEBUG) Log.v(TAG, "  Start tracking!");                           state.startTracking(this, target);                       } else if (isLongPress() && state.isTracking(this)) {                           try {                               if (receiver.onKeyLongPress(mKeyCode, this)) {                                   if (DEBUG) Log.v(TAG, "  Clear from long press!");                                   state.performedLongPress(this);                                   res = true;                               }                           } catch (AbstractMethodError e) {                           }                       }                   }                   return res;               }               case ACTION_UP:                   if (DEBUG) Log.v(TAG, "Key up to " + target + " in " + state                           + ": " + this);                   if (state != null) {                       state.handleUpEvent(this);                   }                   return receiver.onKeyUp(mKeyCode, this);               case ACTION_MULTIPLE:                   final int count = mRepeatCount;                   final int code = mKeyCode;                   if (receiver.onKeyMultiple(code, count, this)) {                       return true;                   }                   if (code != KeyEvent.KEYCODE_UNKNOWN) {                       mAction = ACTION_DOWN;                       mRepeatCount = 0;                       boolean handled = receiver.onKeyDown(code, this);                       if (handled) {                           mAction = ACTION_UP;                           receiver.onKeyUp(code, this);                       }                       mAction = ACTION_MULTIPLE;                       mRepeatCount = count;                       return handled;                   }                   return false;           }           return false;       }  

该函数中主要根据相应的逻辑回调了receiver中的onKeyDown, onKeyUp,OnKeyLongPress, OnKeyMultiple函数。View中onKeyDown和onKeyUp有自己默认的处理,主要处理presse状态,长按检测,onCick回调。而OnKeyLongPress和OnKeyMultiple为空实现。对于Activity的OnKeyDown和onKeyUp函数主要实现按数字启动打电话程序( onKeyDown)以及back键的onBackPressed回调(onKeyUp)

如果按键消息在View树内部和Activity中没有被处理,就会调用到PhoneWindow的OnKeyDown和OnKeyUp函数,这是按键消息的最后处理机会,在PhoneWindow的OnKeyDown和OnKeyUp函数中主要处理了一些系统按键,例如音量键、音乐播放控制按键、照相机键、菜单键、拨号键、Search键等,具体代码就不再贴了。

以上博文主要根据《Android内核剖析》第13章以及Android源码总结而成。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/psyxy.html