Android KeyEvent分发机制

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

Android KeyEvent分发机制

简介

KeyEvent的分发机制和TouchEvent的分发机制略有不同,KeyEvent向下分发的事件没有被消费,并且KeyCode为KEYCODE_DPAD_LEFT,KEYCODE_DPAD_RIGHT,KEYCODE_DPAD_UP,KEYCODE_DPAD_DOWN,那么会按方向查找下一个控件并获取焦点。

触摸事件分发机制传送门: Android触摸事件分发机制源码分析

分发机制分析

先放上整体流程图,稍后再详细解释:

在这里插入图片描述

ViewRootImpl是所有View的顶层容器,所以从ViewRootImpl着手。ViewRootImpl的dispatchInputEvent()方法,向消息队列发出MSG_DISPATCH_INPUT_EVENT消息,Handler处理消息并调用ViewRootImpl的enqueueInputEvent()方法,将QueuedInputEvent插入到未处理KeyEvent队列的尾部。

enqueueInputEvent()方法具体实现:

void enqueueInputEvent(InputEvent event,InputEventReceiver receiver, int flags, boolean processImmediately) {
   
   
    adjustInputEventForCompatibility(event);
    QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);

    QueuedInputEvent last = mPendingInputEventTail;
    if (last == null) {
   
   
        mPendingInputEventHead = q;
        mPendingInputEventTail = q;
    } else {
   
   
        last.mNext = q;
        mPendingInputEventTail = q;
    }
    mPendingInputEventCount += 1;
    Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName,mPendingInputEventCount);

    if (processImmediately) {
   
   
        doProcessInputEvents();
    } else {
   
   
        scheduleProcessInputEvents();
    }
}

keyEvent插入未处理事件队列后,接下来要处理这些事件了。有两种处理方式,直接处理和向Handler发送异步消息处理。这里只分析直接处理的情况。

doProcessInputEvents()方法遍历未处理事件队列逐个处理:

void doProcessInputEvents() {
   
   
        // Deliver all pending input events in the queue.
        while (mPendingInputEventHead != null) {
   
   
            QueuedInputEvent q = mPendingInputEventHead;
            mPendingInputEventHead = q.mNext;
            if (mPendingInputEventHead == null) {
   
   
                mPendingInputEventTail = null;
            }
            q.mNext = null;

            mPendingInputEventCount -= 1;
            Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName,
                    mPendingInputEventCount);

            long eventTime = q.mEvent.getEventTimeNano();
            long oldestEventTime = eventTime;
            if (q.mEvent instanceof MotionEvent) {
   
   
                MotionEvent me = (MotionEvent)q.mEvent;
                if (me.getHistorySize() > 0) {
   
   
                    oldestEventTime = me.getHistoricalEventTimeNano(0);
                }
            }
            mChoreographer.mFrameInfo.updateInputEventTime(eventTime, oldestEventTime);

            deliverInputEvent(q);
        }

        // We are done processing all input events that we can process right now
        // so we can clear the pending flag immediately.
        if (mProcessInputEventsScheduled) {
   
   
            mProcessInputEventsScheduled = false;
            mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);
        }
    }

QueuedInputEvent交给deliverInputEvent()方法来处理:

private void deliverInputEvent(QueuedInputEvent q) {
   
   
    Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW,"deliverInputEvent",
        q.mEvent.getSequenceNumber());
    if (mInputEventConsistencyVerifier != null) {
   
   
        mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
    }

    InputStage stage;
    if (q.shouldSendToSynthesizer()) {
   
   
        stage = mSyntheticInputStage;
    } else {
   
   
        stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
    }

    if (stage != null) {
   
   
        stage.deliver(q);
    } else 
7【Android 12】输入事件在App层的分发流程(三) —— KeyEvent处理流程 专注于KeyEvent是如何发送给View层级结构的,其他的暂时不关注。这里的mView是View层级结构的根VIew,对于Activity来说就是DecorView。 阅读详情

相关推荐

Android Framework层KeyEvent按键添加流程

其次,我们找到了Framework层中处理KeyEvent的路径,并在WindowManagerService类中添加了自定义的按键处理逻辑。通过这些步骤,我们可以在Android系统中定制和扩展按键事件的处理能力,为用户提供更丰富和个性化的操作体验。一旦找到了WindowManagerService中处理KeyEvent按键的方法,我们可以添加自定义的按键事件处理逻辑。通过以上的步骤,我们可以在Android Framework层中成功添加和处理自定义的KeyEvent按键事件。

DevGlider的博客 645

Android中的KeyEvent详解

Android中,KeyEvent 是用来表示按键事件的类,可根据对应的事件来处理按键输入,具体包含了关于按键事件的信息,例如按键的代码、动作(按下或释放)以及事件的时间戳,KeyEvent 对象通常在用户与设备上的物理或软件键盘交互时产生,KeyEvent可以帮助开发者创建更加互动和响应式的应用程序

FlyingFish868的博客 6139

keyevent常用键列表

常用键展示 KEYCODE_CALL # 拨号键 5 KEYCODE_ENDCALL # 挂机键 6 KEYCODE_HOME # 按键Home 3 KEYCODE_MENU # 菜单键 82 KEYCODE_BACK # 返回键 4 KEYCODE_SEARCH # 搜索键 84 KEYCODE_CAMERA # 拍照键 2...

shixiaonong_ 2万+

Android——按键事件KeyEvent分发处理流程解析

前言 这次打算来梳理一下 Android Tv 中的按键点击事件 KeyEvent分发处理流程。一谈到点击事件机制,网上资料已经非常齐全了,像什么分发、拦截、处理三大流程啊;或者dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent 啊;再或者返回 true 表示消费,返回 false 不处理啊;还有说整个流程是个 U 型分发处理,什么总经理...

小欣儿的专栏 9547

Android 按键事件(KeyEvent)的分发机制

本内容主要介绍 Android 中 Java 层 按键事件(KeyEvent) 的分发机制。基于 Android 9.0 的源码进行介绍。

步入人工智能 3836

androidkeyevent方法,Android View框架总结(九)KeyEvent事件分发机制

本篇开始分析按键消息事件分发(PS:本篇文章中源码均是android 6.0,请知晓)先看下Agenda:ViewRootImpl中的dispatchInputEvent方法View.dispatchKeyEvent方法ViewGroup.dispatchKeyEvent方法Activity.dispatchKeyEvent方法按键消息事件时序图ViewRootImpl中的dispatchInpu...

weixin_39680121的博客 1451

安卓中的虚拟键盘实现,KeyEvent的事件分发、处理机制。EditText是如何将KeyEvent事件转为字符输入的?

一、实现一个可以模拟输入的软键盘 一开始,我们的需求是在用户经常使用的部分界面中,增加虚拟软键盘,减少用户对于外接键盘的依赖 如图,在整单改价界面右侧增加了方便用户快捷输入的软键盘,用户不需要使用外接键盘,即可完成常见的商品改价等操作。 那么这个代码逻辑实现起来比较简单,因为业务中有许多类似界面需要使用该软键盘功能,所以我们将它单独封装为一个View: mView = View.inflate(context, R.layout.res_keypad_view, this...

王凯旋的博客 5978

android event机制,Android View框架总结(九)KeyEvent事件分发机制

本篇开始分析按键消息事件分发(PS:本篇文章中源码均是android 6.0,请知晓)先看下Agenda:ViewRootImpl中的dispatchInputEvent方法View.dispatchKeyEvent方法ViewGroup.dispatchKeyEvent方法Activity.dispatchKeyEvent方法按键消息事件时序图ViewRootImpl中的dispatchInpu...

weixin_26774169的博客 577

Android View框架总结(九)KeyEvent事件分发机制

本篇开始分析按键消息事件分发(PS:本篇文章中源码均是android 6.0,请知晓)先看下Agenda: ViewRootImpl中的dispatchInputEvent方法 View.dispatchKeyEvent方法 ViewGroup.dispatchKeyEvent方法 Activity.dispatchKeyEvent方法 按键消息事件时序图 ViewRootImpl中的di

欢迎关注公众号:【码农突围】,公号后台回复9999,可以获取一份500页的LeetCode刷题笔记。 9453

android key事件分发与焦点事件的传递

andorid KeyEvent的传递流程和焦点的关系

hierophantzw的专栏 2678

KeyEvent分发机制

​按键事件分发机制

Z_Dong_的博客 651

Android强行进阶—按键事件&焦点事件攻略

监听器的优先级高于Callback的回调,也就是说OnKeyListener的函数优先Callback的onKeyDown等等函数的回调。View的Callback回调要早于Activity,Activity的回调早于PhoneWindow。优先级高的消费KeyEvent,优先级低的不再受理该事件。下面通过时序图对上文KeyEvent做一个整体流程的阐释(虽然不能准备表达意思)

2401_84909930的博客 331

Android dispatchKeyEvent事件分发详解,简单易懂

本文逻辑流程图基于Android 8.0,其他版本可能略有不同但是主体流程是一样的。 前言 KeyEvent分发是从Activity->ViewGroup->View。 KeyEvent的组成 KeyEvent的主要包含两个部分:action和键值 action Action_up或者Action_down代表是按下还是抬起 键值 比如数字键等 KeyEvent常用方法 - ge...

snailyy 1万+

matlab edittext 回车,安卓中的虚拟键盘实现,KeyEvent的事件分发、处理机制。EditText是如何将KeyEvent事件转为字符输入的?...

目录一、实现一个可以模拟输入的软键盘一开始,我们的需求是在用户经常使用的部分界面中,增加虚拟软键盘,减少用户对于外接键盘的依赖 如图,在整单改价界面右侧增加了方便用户快捷输入的软键盘,用户不需要使用外接键盘,即可完成常见的商品改价等操作。那么这个代码逻辑实现起来比较简单,因为业务中有许多类似界面需要使用该软键盘功能,所以我们将它单独封装为一个View:mView = View.inflate(co...

weixin_30346649的博客 569

Android dispatchKeyEvent

dispatchKeyEvent 时间分发机制 先 Activity dispatchKeyEvent 再 View dispatchKeyEvent 再 子View 若返回true,则不再向下分发

xifengwai的专栏 2697

Android强行进阶—按键事件&焦点事件攻略(1)

监听器的优先级高于Callback的回调,也就是说OnKeyListener的函数优先Callback的onKeyDown等等函数的回调。View的Callback回调要早于Activity,Activity的回调早于PhoneWindow。优先级高的消费KeyEvent,优先级低的不再受理该事件。下面通过时序图对上文KeyEvent做一个整体流程的阐释(虽然不能准备表达意思)

2301_78416573的博客 544

电视按键事件的处理(1)

首先大致看看安卓按键事件的默认分发机制 package com.example.keytest; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; public class Ma

王家胜的博客 296
上一篇: 通过KeyEvent选中控件
下一篇: 记一次Android OOM探险之旅
ws_lm
博客等级 码龄15年 3粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值