回到Step 18中,我们继续分析EventHub.getEvent函数的实现。
在中间的for循环里面,首先会检查当前是否有输入设备被关闭,如果有,就返回一个设备移除的事件给调用方:
  1. // Report any devices that had last been added/removed.
  2. if (mClosingDevices != NULL) {
  3. device_t* device = mClosingDevices;
  4. LOGV("Reporting device closed: id=0x%x, name=%s\n",
  5. device->id, device->path.string());
  6. mClosingDevices = device->next;
  7. if (device->id == mFirstKeyboardId) {
  8. outEvent->deviceId = 0;
  9. } else {
  10. outEvent->deviceId = device->id;
  11. }
  12. outEvent->type = DEVICE_REMOVED;
  13. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
  14. delete device;
  15. mNeedToSendFinishedDeviceScan = true;
  16. return true;
  17. }
接着,检查当前是否有新的输入设备加入进来:
  1. if (mOpeningDevices != NULL) {
  2. device_t* device = mOpeningDevices;
  3. LOGV("Reporting device opened: id=0x%x, name=%s\n",
  4. device->id, device->path.string());
  5. mOpeningDevices = device->next;
  6. if (device->id == mFirstKeyboardId) {
  7. outEvent->deviceId = 0;
  8. } else {
  9. outEvent->deviceId = device->id;
  10. }
  11. outEvent->type = DEVICE_ADDED;
  12. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
  13. mNeedToSendFinishedDeviceScan = true;
  14. return true;
  15. }

接着,再检查是否需要结束监控输入事件:

  1. if (mNeedToSendFinishedDeviceScan) {
  2. mNeedToSendFinishedDeviceScan = false;
  3. outEvent->type = FINISHED_DEVICE_SCAN;
  4. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
  5. return true;
  6. }

最后,就是要检查当前是否有还未处理的输入设备事件发生了:

  1. // Grab the next input event.
  2. for (;;) {
  3. // Consume buffered input events, if any.
  4. if (mInputBufferIndex < mInputBufferCount) {
  5. const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
  6. const device_t* device = mDevices[mInputDeviceIndex];
  7. LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
  8. (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
  9. if (device->id == mFirstKeyboardId) {
  10. outEvent->deviceId = 0;
  11. } else {
  12. outEvent->deviceId = device->id;
  13. }
  14. outEvent->type = iev.type;
  15. outEvent->scanCode = iev.code;
  16. if (iev.type == EV_KEY) {
  17. status_t err = device->layoutMap->map(iev.code,
  18. & outEvent->keyCode, & outEvent->flags);
  19. LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
  20. iev.code, outEvent->keyCode, outEvent->flags, err);
  21. if (err != 0) {
  22. outEvent->keyCode = AKEYCODE_UNKNOWN;
  23. outEvent->flags = 0;
  24. }
  25. } else {
  26. outEvent->keyCode = iev.code;
  27. }
  28. outEvent->value = iev.value;
  29. // Use an event timestamp in the same timebase as
  30. // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
  31. // as expected by the rest of the system.
  32. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
  33. return true;
  34. }
  35. // Finish reading all events from devices identified in previous poll().
  36. // This code assumes that mInputDeviceIndex is initially 0 and that the
  37. // revents member of pollfd is initialized to 0 when the device is first added.
  38. // Since mFDs[0] is used for inotify, we process regular events starting at index 1.
  39. mInputDeviceIndex += 1;
  40. if (mInputDeviceIndex >= mFDCount) {
  41. break;
  42. }
  43. const struct pollfd& pfd = mFDs[mInputDeviceIndex];
  44. if (pfd.revents & POLLIN) {
  45. int32_t readSize = read(pfd.fd, mInputBufferData,
  46. sizeof(struct input_event) * INPUT_BUFFER_SIZE);
  47. if (readSize < 0) {
  48. if (errno != EAGAIN && errno != EINTR) {
  49. LOGW("could not get event (errno=%d)", errno);
  50. }
  51. } else if ((readSize % sizeof(struct input_event)) != 0) {
  52. LOGE("could not get event (wrong size: %d)", readSize);
  53. } else {
  54. mInputBufferCount = readSize / sizeof(struct input_event);
  55. mInputBufferIndex = 0;
  56. }
  57. }
  58. }

未处理的输入事件保存在成员变量mInputBufferData中,如果有的话,就可以直接返回了,否则的话,就要通过系统调用poll来等待输入设备上发生新的事件了,在我们这个场景中,就是等待键盘有键被按下或者松开了。:

  1. int pollResult = poll(mFDs, mFDCount, -1);

这里的mFDs包含了我们所要监控的输入设备的打开文件描述符,这是在前面的openPlatformInput函数中初始化的。

转载于:https://blog.51cto.com/shyluo/966621

Android应用程序键盘(Keyboard)消息处理机制分析(8)相关推荐

  1. Android系统中的Binder通信机制分析(7)- Java 层的 Binder 机制

    声明 其实对于Android系统Binder通信的机制早就有分析的想法,记得2019年6.7月份Mr.Deng离职期间约定一起对其进行研究的,但因为我个人问题没能实施这个计划,留下些许遗憾- 文中参考 ...

  2. Android应用程序键盘(Keyboard)消息处理机制分析(3)

    Step 15. Looper.pollOnce 这个函数定义在frameworks/base/libs/utils/Looper.cpp文件中,具体可以参考前面Android应用程序消息处理机制(L ...

  3. Android应用程序键盘(Keyboard)消息处理机制分析(12)

    Step 12. InputChannel.openInputChannelPair 这个函数定义在frameworks/base/core/java/android/view/InputChanne ...

  4. Android应用程序线程消息循环模型分析(5)

      从AsyncTask的实现可以看出,当我们第一次创建一个AsyncTask对象时,首先会执行下面静态初始化代码创建一个线程池sExecutor: private static final Bloc ...

  5. Android应用程序线程消息循环模型分析

    出自:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是通过消息来驱动的,即在应用程序的主线程(UI ...

  6. 以下未发布-Android的多线程以及异步消息处理机制,android移动开发基础案例教程源码

    1.Message: Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间进行数据交换.除了 what 字段,还可以使用 arg1 和 arg2 来携带整型数据,使用 ...

  7. Android应用程序键盘(Keyboard)消息处理机制分析(20)

    Step 24. InputQueue.dispatchKeyEvent 这个函数定义在frameworks/base/core/java/android/view/InputQueue.java文件 ...

  8. Android应用程序键盘(Keyboard)消息处理机制分析(26)

    Step 7. LocalWindowManager.removeViewImmediate 这个函数定义在frameworks/base/core/java/android/view/Window. ...

  9. Android应用程序键盘(Keyboard)消息处理机制分析(17)

    Step 11. InputDispatcher.dispatchOnceInnerLocked 这个函数定义在frameworks/base/libs/ui/InputDispatcher.cpp文 ...

  10. Android应用程序键盘(Keyboard)消息处理机制分析(14)

    3. InputManager分发键盘消息给应用程序的过程分析 在分析InputManager分发键盘消息给应用程序的过程之前,我们先假设现在没有键盘事件发生,因此,InputManager中的Inp ...

最新文章

  1. 机器学习中常用到的知识点总结
  2. 编程入门python语言是多大孩子学的-不学点编程,将来怎么给孩子辅导作业―Python新手入门教程...
  3. libklel 1.1.0 发布,表达式语言
  4. 计算机多媒体应用软件有超媒体特点吗,计算机应用基础第三套试卷98分
  5. 如何成为有效学习的高手(许岑)——思维导图
  6. printf 地址_C程序显示主机名和IP地址
  7. 前端学习(2223):react之jsx的样式和注释(2)
  8. GIS之旅——研究生总结
  9. CMU 15-213 Introduction to Computer Systems学习笔记(16) Virtual Memory: Concepts
  10. Java编程题——简单下拉框二级联动
  11. 几行代码,把你的小电影全部藏好了!
  12. VC中鼠标移动点击操作
  13. 【windows】win10如何安装使用bitlocker
  14. 形容芝士蛋糕好吃的句子精选
  15. Pycharm2020.1安装中文语言插件教程,不需要汉化
  16. Web---HTML标签总结
  17. 朱清时:中国大学首要问题是如何让学生学到真本事
  18. bzoj4887: [Tjoi2017]可乐(矩阵乘法+快速幂)
  19. python 高斯函数拟合_在python中拟合任意高斯函数,消耗大量内存
  20. 好看的个人主页,导航页HTML源码源码三分钟下载安装

热门文章

  1. Java获取正在执行的函数名
  2. POJ-1094 Sorting it All Out
  3. 安装ipvsadm 用make编译出现错误解决方法
  4. Centos 6.3 修改xorg.conf后 启动失败
  5. 从程序语言排行榜来解读IT及Web的发展
  6. python目录大纲
  7. dreamweaver2020中文版
  8. 【LOJ】#3098. 「SNOI2019」纸牌
  9. Volatile 关键字 内存可见性
  10. 数据库死锁查询及处理