Android用户事件输入路径

  1 输入路径的一般原理
  按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题。按键,鼠标等用户消息消息的处理可分为不同的情况进行判定:
  (1)用户输入根据系统状况是否应该派送。如在ScreenOff的情况下,在按键属于特殊按键的情况下等
  (2)是否有拦截Listener
  (3)对按键事件来讲,是否存在输入法
  (4)是否是焦点终点
  (5)是否为焦点切换按相关键
  这些情况都是设计输入路径需要考虑的基本条件。
  1.1一般的输入路径设计
  该输入路径实际上是指的按键消息(MSG_KEYDOWN,MSG_KEYUP, MSG_LongPress)的输入路径,即从活动主窗口到焦点窗口所经历的路程。
                            

123.jpg (5.46 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:09 上传

 

  将信息输入路径分为两步:
  Step 1)窗口管理器将信息发送到活动窗口
  Step 2)活动窗口通过缺省处理函数将该消息一层层的传递到焦点。
  这样应用程序可以在活动View的处理函数中来预先处理用户输入信息,从而增强应用对用户信息的控制力。
                            

456.jpg (11.41 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:09 上传

 

  传递路径是通过View的缺省处理函数Onxxx来完成。通过ActiveView ->focus->focus->focus的链条关系,一级一级的将按键消息MSG_KEYDOWN,MSG_KEYUP, MSG_CHAR等传递到focus窗口。
                          

789.jpg (6.28 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:12 上传

 

  此时用户按键输入先发送到输入法窗口,经过输入法管理器处理,过滤后将输入法产生的结果放置到焦点View。
  1.3输入系统整体流程
  下面示意图是Android输入系统的数据流途径,通过WM的输入系统线程收集消息,分发到Focus Activity消息队列,然后通过消息系统派发。
                       

147.jpg (38.15 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:13 上传

 

  2 Android输入路径详细描述
  2.1 第一步:用户数据收集及其初步判定
  KeyInputQ在WindowMangerService中建立一个独立的线程InputDeviceReader,使用Native函数readEvent来读取Linux Driver的数据构建RawEvent,放入到KeyQ消息队列中。
                       

258.jpg (9.92 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:14 上传

 

  preProcessEvent()KeyInptQ@KeyInputQueue.java这个是在输入系统中的第一个拦截函数原型。KeyQ重载了preProcessEvent()@WindowManagerService.java。在该成员函数中进行如下动作:
  (1) 根据PowerManager获取的Screen on,Screen off状态来判定用户输入的是否WakeUPScreen。
  (2) 如果按键式应用程序切换按键,则切换应用程序。
  (3) 根据WindowManagerPolicy觉得该用户输入是否投递。
  2.2 第二步 消息分发第一层面
  InputDispatcherThread从KeyQ中读取Events,找到Window Manager中的Focus Window,通过Focus Window记录的mClient接口,将Events专递到Client端。
                           

369.jpg (10.23 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:23 上传

 

  如何将KeyEvent对象传到Client端:
  在前面的章节(窗口管理ViewRoot,Window Manager Proxy)我们已经知道:在客户端建立Window Manager Proxy后,添加窗口到Window Manager service时,带了一个跟客户ViewRoot相关的IWindow接口实例过去,记录在WindowState中的mClient成员变量中。通过IWindow这个AIDL接口实例,Service可以访问客户端的信息,IWindow是Service连接View桥梁。
                    

321.jpg (12.32 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:16 上传

 

  看看在Client ViewRootKeyEvent的分发过程
  IWindow:dispatchKey(event)
  dispatchKey(event)ViewRoot@ViewRoot.java
  ViewRoot.dispatchKey(event)@ViewRoot.java
  message>
  sendMessageAtTime(msg)Handler@Handler.java
  至此我们通过前面的Looper,Handler详解章节的分析结论,我们可以知道Key Message已经放入到应用程序的消息队列。
  2.3第三步:应用消息队列分发
  消息的分发,在Looper,Handler详解章节我们分析了Looper.loop()在最后后面调用了handleMesage。
  …
  ActivityThread.main()
  Looper.loop()
  ViewRoot$RootHandler().dispatch()
  handleMessage
  …。
  注意到在分发的调用msg.target.dispatch(),而这个target在第二层将消息sendMessageAtTime到消息队列时填入了mag.target=this即为msg.target=ViewRoot实例。所有此时handleMessage就是ViewRoot重载的handleMessage函数。
  handlerMessage@ViewRoot@ViewRoot.java
  deliverkeyEvent
  如果输入法存在,dispatchKey到输入法服务。
  否则deliverKeyEventToViewHierarchy@ViewRoot.java
  在这里需要强调的是,输入法的KeyEvent的拦截并没有放入到Window Manager Service中,而是放入到了客户端的RootView中来处理。
  2.4第四步:向焦点进发,完成焦点路径的遍历。
                    

654.jpg (26.7 KB, 下载次数: 0)

下载附件  保存到相册

2012-3-21 10:21 上传

 

  分发函数调用栈
  deliverKeyEventToViewHierarchy@ViewRoot。java
  mView.dispatchKeyEvent:mView是与ViewRoot相对应的Top-Level View。如果mView是一个ViewGroup则分发消息到他的mFocus。
  mView.dispatchKeyEvent @ViewGroup  (ViewRoot@root)
  Event.dispatch
  mFocus.dispatchKeyEevnet
  如果此时的mFocu还是一个ViewGroup,这回将事件专递到下一层的焦点,直到mFocus为一个View。通过这轮调用,就遍历了焦点Path,至此,用户事件传递完成一个段落。
  2.5第五步 缺省处理
  如果事件在上述Focus View没有处理掉,并且为方向键之类的焦点转换相关按键,则转移焦点到下一个View。

Android核心分析之十五Android输入系统之输入路径详解的更多相关文章

  1. Android核心分析之十四Android GWES之输入系统

          Android输入系统 依照惯例,在研究Android输入系统之前给出输入系统的本质描述:从哲学的观点来看,输入系统就是解决从哪里来又将到哪里去问题.输入的本质上的工作就是收集用户输入信息 ...

  2. Android核心分析之十六Android电话系统-概述篇

    Android电话系统之概述篇 首先抛开Android的一切概念来研究一下电话系统的最基本的描述.我们的手机首先用来打电话的,随后是需要一个电话本,随后是PIM,随后是网络应用,随后是云计算,随后是想 ...

  3. Android核心分析之十八Android电话系统之RIL-Java

    Android RIL-Java 123.jpg (2.09 KB, 下载次数: 1) 下载附件  保存到相册 2012-3-21 10:47 上传   RIL-Java在本质上就是一个RIL代理,起 ...

  4. Android 核心分析之十二Android GEWS窗口管理之基本架构原理

    Android GWES之窗口管理之基本构架原理 Android的窗口管理是C/S模式的.Android中的Window是表示Top Level等顶级窗口的概念.DecorView是Window的To ...

  5. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. “全栈2019”Java第六十五章:接口与默认方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. Android核心分析 之十Android GWES之基本原理篇

    Android GWES基本框架篇 我这里的GWES这个术语实际上从Microsoft 的Window上移植过来的,用GWES来表示Android的窗口事件系统不是那么准确,在Android中Wind ...

  8. Android核心分析之二十一Android应用框架之AndroidApplication

    Android Application Android提供给开发程序员的概念空间中Application只是一个松散的表征概念,没有多少实质上的表征.在Android实际空间中看不到实际意义上的应用程 ...

  9. Android核心分析之十九电话系统之GSMCallTacker

    GSMCallTracker在本质上是一个Handler.<IGNORE_JS_OP> 1.jpg (1.52 KB, 下载次数: 1) 下载附件  保存到相册 2012-3-22 11: ...

随机推荐

  1. c/c++常用代码--string trim

    typedef std::basic_string<TCHAR> tstring; inline static void trim(tstring& s){    s.erase( ...

  2. EasyUI datagrid frozencolumn的bug???

    今天碰到了个很蛋疼的问题.我用到了easyui 的 treegrid,内容只显示一列,我把它设置成了冻结列. 在谷歌调试下,因为内容比较多,所以,会有竖向的滚动条.但是,到了ie和火狐,滚动条神奇般没 ...

  3. 转载:SQL索引一步到位

    原文: http://www.cnblogs.com/AK2012/archive/2013/01/04/2844283.html SQL索引一步到位(此文章为“数据库性能优化二:数据库表优化”附属文 ...

  4. Spring项目跟Axis2结合

    本文的前提是已经有一个Spring的项目,在此基础上如何跟Axis2进行结合,开发出WebService服务和调用WebService服务. 1.开放WebService服务    1.引入必要的ja ...

  5. bzoj 2327 构图暴力判断+独立集个数

    首先我们可以处理出10^6以内的所有的勾股数,如果我们有2*i-1和2*j互质, 那么A=(2*i-1)*(2*i-1)+(2*i-1)*(2*j),B=2*j*j+(2*i-1)*(2*j)为互质 ...

  6. 转载:百度原CTO李一男经典语录

    原文地址:http://www.cnblogs.com/marvin/archive/2010/01/20/1652088.html 百度原CTO李一男经典语录 [1]好好规划自己的路,不要跟着感觉走 ...

  7. Flash Attribute

    参考:http://www.open-open.com/lib/view/open1397266120028.html 为解决POST/Forward/GET出现的重复提交数据问题,改用POST/Re ...

  8. Leetcode#166 Fraction to Recurring Decimal

    原题地址 计算循环小数 先把负数转化成正数,然后计算,最后添加符号 当被除数重复出现的时候,说明开始循环了,所以用一个map保存所有遇到的被除数 需要考虑溢出问题,这也是本题最恶心的地方,看看通过率吧 ...

  9. linux下安装vsftp

    1. yum安装vsftp # yum install vsftpd 2. 配置Vsftpd 安装完之后我们要对它进行配置,才能正常使用.编辑vsftpd的配置文件vi /etc/vsftpd/vsf ...

  10. .NET设计模式(16):模版方法(Template Method)(转)

    摘要:Template Method模式是比较简单的设计模式之一,但它却是代码复用的一项基本的技术,在类库中尤其重要. 主要内容 1.概述 2.Template Method解说 3..NET中的Te ...