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

简介:

      Step 36. ViewRoot.finishInputEvent

         这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. public final class ViewRoot extends Handler implements ViewParent,  
  2.         View.AttachInfo.Callbacks {  
  3.     ......  
  4.   
  5.     private void finishInputEvent() {  
  6.         ......  
  7.   
  8.         if (mFinishedCallback != null) {  
  9.             mFinishedCallback.run();  
  10.             mFinishedCallback = null;  
  11.         } else {  
  12.             ......  
  13.         }  
  14.     }  
  15.   
  16.     ......  
  17. }  

         ViewRoot类里面的成员变量mFinishedCallback是在前面Step 25中由InputQueue设置的,它是一个Runnable对象,实际类型是定义在InputQueue的内部类FinishedCallback,因此,这里调用它的run方法时,接下来就会调用InputQueue的内部类FinishedCallback的run成员函数:

  1. public final class InputQueue {  
  2.     ......  
  3.   
  4.     private static class FinishedCallback implements Runnable {  
  5.         ......  
  6.   
  7.         public void run() {  
  8.             synchronized (sLock) {  
  9.                 ......  
  10.   
  11.                 nativeFinished(mFinishedToken);  
  12.                   
  13.                 ......  
  14.             }  
  15.         }  
  16.   
  17.         ......  
  18.     }  
  19.   
  20.     ......  
  21. }  

        这里它调用外部类InputQueue的本地方法nativeFinished来进一步处理。

       Step 37.  InputQueue.nativeFinished

        这个函数定义在frameworks/base/core/jni/android_view_InputQueue.cpp文件中:

  1. static void android_view_InputQueue_nativeFinished(JNIEnv* env, jclass clazz,  
  2.         jlong finishedToken) {  
  3.     status_t status = gNativeInputQueue.finished(  
  4.         env, finishedToken, false /*ignoreSpuriousFinish*/);  
  5.   
  6.     ......  
  7. }  
        这个函数只是简单只调用NativeInputQueue的finished方法来进一处处理。

 

        Step 38. NativeInputQueue.finished

        这个函数定义在frameworks/base/core/jni/android_view_InputQueue.cpp文件中:

  1. status_t NativeInputQueue::finished(JNIEnv* env, jlong finishedToken, bool ignoreSpuriousFinish) {  
  2.     int32_t receiveFd;  
  3.     uint16_t connectionId;  
  4.     uint16_t messageSeqNum;  
  5.     parseFinishedToken(finishedToken, &receiveFd, &connectionId, &messageSeqNum);  
  6.   
  7.     { // acquire lock  
  8.         AutoMutex _l(mLock);  
  9.   
  10.         ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);  
  11.         ......  
  12.   
  13.         sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);  
  14.         ......  
  15.   
  16.         connection->messageInProgress = false;  
  17.   
  18.         status_t status = connection->inputConsumer.sendFinishedSignal();  
  19.           
  20.         ......  
  21.     } // release lock  
  22.   
  23.     return OK;  
  24. }  
        这个函数最重要的参数便是finishedToken了,通过它可以获得之前通知Java层的InputQueue类来处理键盘事件的Connection对象,它的值是在上面的Step 21(NativeInputQueue.handleReceiveCallback)中生成的:

  1. finishedToken = generateFinishedToken(receiveFd, connection->id, connection->messageSeqNum);  

        函数generateFinishedToken的定义如下:

  1. jlong NativeInputQueue::generateFinishedToken(int32_t receiveFd, uint16_t connectionId,  
  2.         uint16_t messageSeqNum) {  
  3.     return (jlong(receiveFd) << 32) | (jlong(connectionId) << 16) | jlong(messageSeqNum);  
  4. }  

        它的实现很简单,只是把receiveFd(前向管道的读端文件描述符)、connectionId(Client端的InputChannel对应的Connection对象在NativeInputQueue中的索引)和messageSeqNum(键盘消息的序列号)三个数值通过移位的方式编码在一个jlong值里面,即编码在上面的finishedToken参数里面。

 

        因此,在上面的finished函数里面,首先就是要对参数值finishedToken进行解码,把receiveFd、connectionId和messageSeqNum三个值分别取回来:

  1. parseFinishedToken(finishedToken, &receiveFd, &connectionId, &messageSeqNum);  

       parseFinishedToken的定义如下:

  1. void NativeInputQueue::parseFinishedToken(jlong finishedToken,  
  2.         int32_t* outReceiveFd, uint16_t* outConnectionId, uint16_t* outMessageIndex) {  
  3.     *outReceiveFd = int32_t(finishedToken >> 32);  
  4.     *outConnectionId = uint16_t(finishedToken >> 16);  
  5.     *outMessageIndex = uint16_t(finishedToken);  
  6. }  

       有了这个receiveFd和connectionId之后,就可以把相应的Connection对象取回来了:

  1. ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);  
  2.         ......  
  3.   
  4. sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);  

       接下来就是调用这个connection对象中的inputConsumer对象来发送信号通知Server端的InputChannel,应用程序这一侧处理完刚才发生的键盘事件了:

  1. status_t status = connection->inputConsumer.sendFinishedSignal();  




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966645,如需转载请自行联系原作者
目录
打赏
0
0
0
0
235
分享
相关文章
探索Android与iOS的隐私保护机制
在数字化时代,移动设备已成为我们生活的一部分,而隐私安全是用户最为关注的问题之一。本文将深入探讨Android和iOS两大主流操作系统在隐私保护方面的策略和实现方式,分析它们各自的优势和不足,以及如何更好地保护用户的隐私。
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
81 2
深入探索Android与iOS的多任务处理机制
在移动操作系统领域,Android和iOS各有千秋,尤其在多任务处理上展现出不同的设计理念和技术实现。本文将深入剖析两大平台在后台管理、资源分配及用户体验方面的策略差异,揭示它们如何平衡性能与电池寿命,为用户带来流畅而高效的操作体验。通过对比分析,我们不仅能够更好地理解各自系统的工作机制,还能为开发者优化应用提供参考。
深入探索安卓系统的多任务处理机制
【10月更文挑战第21天】 本文旨在为读者提供一个关于Android系统多任务处理机制的全面解析。我们将从Android操作系统的核心架构出发,探讨其如何管理多个应用程序的同时运行,包括进程调度、内存管理和电量优化等方面。通过深入分析,本文揭示了Android在处理多任务时所面临的挑战以及它如何通过创新的解决方案来提高用户体验和设备性能。
178 1
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
89 1
探索安卓与iOS的隐私保护机制####
【10月更文挑战第15天】 本文深入剖析了安卓和iOS两大操作系统在隐私保护方面的策略与技术实现,旨在揭示两者如何通过不同的技术手段来保障用户数据的安全与隐私。文章将逐一探讨各自的隐私控制功能、加密措施以及用户权限管理,为读者提供一个全面而深入的理解。 ####
217 1
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
157 2
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
220 76
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
79 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等