为什么KeyEvent会先被PhoneWindowManager.java(Ics 4.03) 文件的 interceptKeyBeforeDispatching()处理;

为什么KeyEvent会先被PhoneWindowManager.java(Ics 4.03) 文件的
interceptKeyBeforeDispatching()处理;
一些按键HOME/MENU/SEARCH需要特殊处理,不会发送到activity,android系统都是在
interceptKeyBeforeDispatching()做特殊处理,那么为什么按键会先被这个函数接受,而不是别的函数,系统Event的传递流程是什么?
下面会一步步揭晓;
SystemServer.java
System.loadLibrary("android_servers");
libandroid_servers:
extern "C" jintJNI_OnLoad(JavaVM* vm, void* reserved)
{
   register_android_server_InputManager(env);
}
这样:
Java层里面 nativeInit就对应 native层的: android_server_InputManager_nativeInit
建立javac的关联:
native,会有一个thread一直去polling linuxinput输入;
如果是TYPE_KEY的话,会call下列函数:
InputDispatcher.cpp  
dispatchKeyLocked()->doInterceptKeyBeforeDispatchingLockedInterruptible()
->mPolicy->interceptKeyBeforeDispatching()
mPolicy实体 C 层的com_android_server_InputManager.cpp
那么C层的interceptKeyBeforeDispatching()是如何实现的呢?
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching,clazz,
           "interceptKeyBeforeDispatching",
           "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)J");
所以C层的interceptKeyBeforeDispatching对应java层的:
InputManager.java->  interceptKeyBeforeDispatching;
这样就来到的java的世界,在C层的keyevent就传递给了java层;
再来看java层的处理流程
public long interceptKeyBeforeDispatching(InputWindowHandlefocus,
                KeyEvent event, intpolicyFlags) {
           return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(
                    focus, event, policyFlags);
       }
所以interceptKeyBeforeDispatching函数最终会调用
finalInputMonitor mInputMonitor = new InputMonitor(this);
    public long interceptKeyBeforeDispatching(
         
        return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event,policyFlags);
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 系统PhoneWindowManager.java处理系统级别事件的一个重要类。如果底层按键通过 input 上报之后,该事件最终会被传递到 PhoneWindowManager.java 处理。在 PhoneWindowManager.java ,可以通过重写 onKeyDown 和 onKeyUp 方法来处理按键事件。在这两个方法,你可以获取到按键的键值和按键状态,并进行相应的处理。 为了测试和验证按键事件,可以使用 Android 系统自带的 adb 工具,通过命令行模拟按键事件。具体步骤如下: 1. 首先需要连接 Android 设备到电脑上,并启用 USB 调试模式。 2. 在电脑上打开命令行终端,进入 adb 工具所在的目录。 3. 使用 adb shell 命令进入 Android 设备的 shell 环境。 4. 使用 input 命令模拟按键事件。例如,模拟按下 F1 按键: ``` input keyevent KEYCODE_F1 ``` 5. 在 PhoneWindowManager.java 的 onKeyDown 或 onKeyUp 方法添加日志打印语句,以便查看是否能够正确地获取到按键事件的键值和按键状态。例如: ``` @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.d(TAG, "onKeyDown: keyCode = " + keyCode + ", event = " + event); return super.onKeyDown(keyCode, event); } ``` 6. 重启 Android 设备,确保修改代码生效。 7. 使用命令行模拟按键事件,观察 PhoneWindowManager.java 的日志输出,验证按键事件是否被正确地处理。 注意,以上步骤只是一个简单的测试过程,实际情况可能需要更加复杂的测试和验证。同时,在处理按键事件时,需要注意安全性和兼容性等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值