引用:http://www.jtben.com/document/919575
背景AndroidAutoTest tool是通过ADB shell getevent 命令从android设备获取事件数据来实现事件录制的。然而获取的原始事件数据是字符与16进制数组成的字符串序列,不具备可读性及可修改性。根据项目设计要求,需根据监听结果实时的动态生成可执行的python脚本,以便于后期事件回放。从getevent获取的原始事件数据示例如下: 4244-540927: /dev/input/event0: 0003 0000 0000009e 4244-541083: /dev/input/event0: 0003 0001 000001c7 4244-541182: /dev/input/event0: 0001 014a 00000001 4244-541283: /dev/input/event0: 0000 0000 00000000 4244-573333: /dev/input/event0: 0001 014a 00000000 4244-573473: /dev/input/event0: 0000 0000 00000000 4246-190284: /dev/input/event0: 0003 0000 00000080 4246-190440: /dev/input/event0: 0003 0001 000000a4 4246-190541: /dev/input/event0: 0001 014a 00000001 4246-190622: /dev/input/event0: 0000 0000 00000000 4246-238300: /dev/input/event0: 0001 014a 00000000 4246-238454: /dev/input/event0: 0000 0000 00000000 4247-704749: /dev/input/event0: 0003 0000 00000084 4247-704904: /dev/input/event0: 0003 0001 0000011e 4247-705004: /dev/input/event0: 0001 014a 00000001 4247-705085: /dev/input/event0: 0000 0000 00000000 4247-750322: /dev/input/event0: 0001 014a 00000000 4247-750408: /dev/input/event0: 0000 0000 00000000
KeyDown(102) Delay(17) KeyUp(102) Delay(1563) TouchDown(158,455) Delay(33) TouchUp() Delay(1617) TouchDown(128,164) Delay(48) TouchUp() Delay(1466) TouchDown(132,286) Delay(46) TouchUp() 实现过程整个过程最主要的工作就是解析事件数据流,即将数据流中解析成一个个完整独立的事件。 数据结构以下2个类是解析过程中使用的主要数据结构:
事件监听数据的获取事件数据读取是通过调用ddmslib中的IDevice提供的public void executeShellCommand(String command, IShellOutputReceiver receiver, int maxTimeToOutputResponse)接口函数来实现的,此处command参数为:”getevent -t”。自定义一个实现了IShellOutputReceiver接口的MultiLineReceiver子类实例receiver,每当设备有事件发生时,receiver中实现的回调函数processNewLines(String[] lines)就会被调用,其参数lines就是从设备获取到的事件数据。接下来在processNewLines函数中解析lines即可。 监听数据解析本节描述如何将原始事件数据中解析成事件。此部分由一个EventParse类完成。 事件类型
其他所有事件都是上述事件中的一种或多种的组合。 事件数据提取从android设备读取的原始事件流由一行行如: 422-211293: /dev/input/event0: 001 014a 00000001 的字符串组成,从左到右可以得到如下信息:
这样每一行都可以得到一个实例化的EventItem对象。这里一个EventItem对象就表示一个事件元素 事件识别一个完整的keydown、TouchDown或TouchUp等事件是由一个或多个事件元素组成。通常一个完整的事件产生后会紧跟着一个事件同步行,标志一个完整事件的结束,该行数据由全零组成。开始处理前实例化一个空的RawInputEvent对象,然后我们可以一行一行的如下处理来填充这个对象:
当读到一个事件同步行时,一个完整独立的事件就完成了,RawInputEvent实例中已经包含了该事件的完整数据。然后对该实例各属性进行判断来识别事件类型,具体如下:
脚本生成每解析出一个事件,我们就向录制脚本内容中添加一行对应代码,该行是一个已定义好的python函数的语句,表示执行一个事件动作,其参数就是该类型事件所必要的属性。函数与事件类型的对应关系如下:
另外,每个事件发生的时间是不同的,两两之间有一定的间隔。在向脚本中新添加一行事件前,首先计算当前添加时间与上一事件的添加事件的差值s,然后插入一行python函数代码:Delay(s),表示两事件之间发生时间的间隔,再将当前事件代码添加进脚本中。 脚本运行一次录制完成后,得到的脚本内容是由一连串python函数语句组成,示例如下图所示: |