7【Android 12】输入事件在App层的分发流程(三) —— KeyEvent处理流程

本文详细解析了KeyEvent在Android应用中的传递流程,从ViewRootImpl到Activity和PhoneWindow,重点讲解了焦点机制、dispatchKeyEvent方法和View层级间的交互。了解KeyEvent如何逐级传递,关键在于焦点的追踪和View的分发逻辑。

在这里插入图片描述

7 KeyEvent事件发送流程

7.1 ViewRootImpl.ViewPostImeInputStage.processKeyEvent

        private int processKeyEvent(QueuedInputEvent q) {
   
   
            final KeyEvent event = (KeyEvent)q.mEvent;

		   ......	

            // Deliver the key to the view hierarchy.
            if (mView.dispatchKeyEvent(event)) {
   
   
                if (ViewDebugManager.DEBUG_ENG) {
   
   
                    Log.v(mTag, "App handle key event: event = " + event + ", mView = " + mView
                            + ", this = " + this);
                }
                return FINISH_HANDLED;
            }

		   ......	
        }

专注于KeyEvent是如何发送给View层级结构的,其他的暂时不关注。

这里的mView是View层级结构的根VIew,对于Activity来说就是DecorView。

7.2 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;

		......

        if (!mWindow.isDestroyed()) {
   
   
            final Window.Callback cb = mWindow.getCallback();
            final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
                    : super.dispatchKeyEvent(event);
            if (handled) {
   
   
                return true;
            }
        }

        return isDown ? mWindow.onKeyDown(mFeatureId, event.getKeyCode(), event)
                : mWindow.onKeyUp(mFeatureId, event.getKeyCode(), event);
    }

这里的mWIndow即PhoneWindow,PhoneWIndow的callback是Activity.attach的时候通过PhoneWindow.setCallback设置的,传入的是Activity自己。

那么这里的逻辑是,先调用Activity.dispatchKeyEvent去处理KeyEvent,如果Activity能够处理,那么当前输入事件被认为处理完成。否则,调用PhoneWindow.onKeyDown或者PhoneWindow.onKeyUp处理。

7.3 Activity.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.
     */
    public boolean dispatchKeyEvent(KeyEvent event) {
   
   
        onUserInteraction();

        // Let action bars open menus in response to the menu key prioritized over
        // the window handling it
        final int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_MENU &&
                mActionBar != null && mActionBar.onMenuKeyEvent(event)) {
   
   
            return true;
        }

        Window win = getWindow();
        if (win.superDispatchKeyEvent(event)) {
   
   
            return true;
        }
        View decor = mDecor;
        if (
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值