UiAutomator源码分析之注入事件
上一篇文章《UiAutomator源码分析之UiAutomatorBridge框架》中我们把UiAutomatorBridge以及它相关的类进行的描述,往下我们会尝试根据两个实例将这些类给串联起来,我准备做的是用如下两个很有代表性的实例:
- 注入事件
- 获取控件
1. UiObject.pressHome顺序图
2.这些类是什么时候初始化的
/* */ UiAutomatorBridge(UiAutomation uiAutomation)
/* */ {
/* 48 */ this.mUiAutomation = uiAutomation;
/* 49 */ this.mInteractionController = new InteractionController(this);
/* 50 */ this.mQueryController = new QueryController(this);
/* */ }
3. 代码跟踪
public boolean pressHome() {
218 Tracer.trace();
219 waitForIdle();
220 return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
221 KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
222 KEY_PRESS_EVENT_TIMEOUT);
223 }
- 获得UiDevice对象保存的UiAutomatorBridge对象。着两个对象都是在运行时初始化的,不清楚的话请翻看上面提到的文章
- 通过UiAutomatorBridge对象获得上面章节初始化的InteractionController对象
- 调用InteractionController对象的sendKeyAndWaitForEvent方法,里面参数关键是第一个keycode和第二个eventType
- keycode:代表我们要注入的是按下哪个按键的事件,比如这里我们是KEYCODE_HOME
- eventType:代表我们注射了该事件后预期会获得窗口返回来的哪种AccessibilityEvent类型,比如我们这里是TYPE_WINDOW_CONTENT_CHANGE
进入InteractionController类的sendKeyAndWaitForEvent:
/* */ public boolean sendKeyAndWaitForEvent(final int keyCode, final int metaState, int eventType, long timeout)
/* */ {
/* 188 */ Runnable command = new Runnable()
/* */ {
/* */ public void run() {
/* 191 */ long eventTime = SystemClock.uptimeMillis();
/* 192 */ KeyEvent downEvent = new KeyEvent(eventTime, eventTime, 0, keyCode, 0, metaState, -1, 0, 0, 257);
/* */
/* */
/* 195 */ if (InteractionController.this.injectEventSync(downEvent)) {
/* 196 */ KeyEvent upEvent = new KeyEvent(eventTime, eventTime, 1, keyCode, 0, metaState, -1, 0, 0, 257);
/* */
/* */
/* 199 */ InteractionController.this.injectEventSync(upEvent);
/* */ }
/* */
/* */ }
/* 203 */ };
/* 204 */ return runAndWaitForEvents(command, new WaitForAnyEventPredicate(eventType), timeout) != null;
/* */ }
代码中创建了一个Runnable的线程,线程里面run重写方法要做的事情就是去做注入事件的事情,那么为什么我们不直接去调用事件而需要创建一个线程了,这是因为我们在注入完事件之后还要去等待我们上面定义的预期的eventType是否有出现来判断我们的事件注入究竟是否成功,这个就是204行runAndWaitForEvents做的事情。但我们这里还是先看下线程中是如何注入事件的:
/* */ private boolean injectEventSync(InputEvent event) {
/* 655 */ return this.mUiAutomatorBridge.injectInputEvent(event, true);
/* */ }
再跟踪到UiAutomatorBridge对象:
/* */ public boolean injectInputEvent(InputEvent event, boolean sync) {
/* 70 */ return this.mUiAutomation.injectInputEvent(event, sync);
/* */ }
可以看到最终还是通过UiAutomation来注入事件的,和我们的预期是一致的。
/* */ private AccessibilityEvent runAndWaitForEvents(Runnable command, UiAutomation.AccessibilityEventFilter filter, long timeout)
/* */ {
/* */ try
/* */ {
/* 161 */ return this.mUiAutomatorBridge.executeCommandAndWaitForAccessibilityEvent(command, filter, timeout);
/* */ }
/* */ catch (TimeoutException e) {
/* 164 */ Log.w(LOG_TAG, "runAndwaitForEvent timedout waiting for events");
/* 165 */ return null;
/* */ } catch (Exception e) {
/* 167 */ Log.e(LOG_TAG, "exception from executeCommandAndWaitForAccessibilityEvent", e); }
/* 168 */ return null;
/* */ }
代码又跳到了UiAutomatorBridge这个类
/* */ public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command, UiAutomation.AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException
/* */ {
/* 104 */ return this.mUiAutomation.executeAndWaitForEvent(command, filter, timeoutMillis);
/* */ }
最终把要执行的runnable执行注入事件的线程command和我们预期事件发生后返回来的窗口事件filter以及超时timeoutMillis传进去,UiAutomation就会和AccessibilityService进行交互以注入事件并且等待预期AccessibilityEvent发生或者超时返回。至于UiAutomation是如何和AccessibilityService交互的,这就超出了这个系列文章的范畴了。也许今后有充裕的时间的话我们再来深入去了解分析它。
作者 | 自主博客 | 微信服务号及扫描码 | CSDN |
天地会珠海分舵 | http://techgogogo.com | 服务号:TechGoGoGo扫描码: | http://blog.csdn.net/zhubaitian |
UiAutomator源码分析之注入事件的更多相关文章
- UiAutomator源码分析之获取控件信息
根据上一篇文章<UiAutomator源码分析之注入事件>开始时提到的计划,这一篇文章我们要分析的是第二点: 如何获取控件信息 我们在测试脚本中初始化一个UiObject的时候通常是像以下 ...
- UiAutomator源码分析之UiAutomatorBridge框架
上一篇文章<UIAutomator源码分析之启动和运行>我们描述了uitautomator从命令行运行到加载测试用例运行测试的整个流程,过程中我们也描述了UiAutomatorBridge ...
- [Abp vNext 源码分析] - 13. 本地事件总线与分布式事件总线 (Rabbit MQ)
一.简要介绍 ABP vNext 封装了两种事件总线结构,第一种是 ABP vNext 自己实现的本地事件总线,这种事件总线无法跨项目发布和订阅.第二种则是分布式事件总线,ABP vNext 自己封装 ...
- [置顶] Android源码分析-点击事件派发机制
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17339857 概述 一直想写篇关于Android事件派发机制的文章,却一直没 ...
- Android源码分析-点击事件派发机制
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17339857 概述 一直想写篇关于Android事件派发机制的文章,却一直没 ...
- libevent源码分析二--timeout事件响应
libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1. min_heap ...
- libevent源码分析一--io事件响应
这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1. select l ...
- [Abp 源码分析]九、事件总线
0.简介 事件总线就是订阅/发布模式的一种实现,本质上事件总线的存在是为了降低耦合而存在的. 从上图可以看到事件由发布者发布到事件总线处理器当中,然后经由事件总线处理器调用订阅者的处理方法,而发布者和 ...
- UIAutomator源码分析之启动和运行
通过上一篇<Android4.3引入的UiAutomation新框架官方简介>我们可以看到UiAutomator其实就是使用了UiAutomation这个新框架,通过调用Accessibi ...
随机推荐
- MariaDb数据库管理系统的学习(一)安装示意图
MariaDB数据库管理系统是MySQL的一个分支.主要由开源社区在维护,採用GPL授权许可.开发这个分支的原因之中的一个是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区採用分 ...
- 孙陪你,了解它的权力--Kinect结合的发展Unity3D游戏应用开发
unity3d正在使用kinect三维模型数据控制(它切成脚本) 博主在做项目时须要利用kinect数据控制三维模型中人物的动作.但不是实时控制,而是利用之前获得的骨骼数据,直接控制.无需再利用脚本打 ...
- Cocos2d-x源代码解析(1)——地图模块(3)
接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInf ...
- ecshop广告调用方法
在简单地概括ecshop广告调用该方法,已发表在博客上,在这里,我们总结了以下 :就是官方默认的方法.先加入广告位,然后加入模板的广告位区域,再在将两者相应上. 1.后台 > 广告管理 > ...
- linux下一个apache+tomcat负载均衡和集群
先说一下我的环境 一个ubuntu虚拟机, 一个apache2.2示例 两tomcat1.7示例 1.安装apacheserver sudo apt-get install apache2 假设要重新 ...
- 使用 Advanced Installer 打包 一键安装Web应用程序
原文:使用 Advanced Installer 打包 一键安装Web应用程序 安装预览: 资源下载: 示例安装包 操作流程: 1.新建Asp.net Application. 2.设置应用程序名称和 ...
- list-style-type 去除li 前面的标记(小黑点)
list-style-type 设置标记的样式(或者隐藏标记) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//E ...
- Linux设备驱动实现自己主动创建设备节点
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #inclu ...
- 纯CSS3实现的图片滑块程序 效果非常酷
原文:纯CSS3实现的图片滑块程序 效果非常酷 之前我们经常会看到很多利用jQuery实现的焦点图插件,种类太多了,今天我想给大家分享一款利用纯CSS3实现的图片滑块应用,完全是利用CSS3的相关特性 ...
- Android 源码编译
Google官方资料参考 http://source.android.com/source/building-running.html 1. 环境设置, 下载好源码后,进入源码目录,即之前执行 rep ...