UiAutomator喷射事件的源代码分析
上一篇文章《UiAutomator源代码分析之UiAutomatorBridge框架》中我们把UiAutomatorBridge以及它相关的类进行的描写叙述,往下我们会尝试依据两个实例将这些类给串联起来,我准备做的是用例如以下两个非常有代表性的实例:
- 注入事件
- 获取控件
1. UiObject.pressHome顺序图
2.这些类是什么时候初始化的
3.6章节“初始化UiDevice和UiAutomationBridge“。这里就不做累述。我们这里会看下在初始化UiAutomatorBridge的时候是怎样把QuneryControoler和InteractionController一并初始化了的。详细请看UiAutomatorBridge的构造函数:
/* */ 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 |
天地会珠海分舵 |
服务号:TechGoGoGo 扫描码:
tp=webp" alt="" style="max-width:100%; margin:0px; padding:0px; height:auto!important; word-wrap:break-word!important; width:auto!important; visibility:visible!important"> |
http://blog.csdn.net/zhubaitian |
版权声明:本文博客原创文章。博客,未经同意,不得转载。
UiAutomator喷射事件的源代码分析的更多相关文章
- Robotium原则的实施源代码分析
从前面的章节<Robotium源代码分析之Instrumentation进阶>中我们了解到了Robotium所基于的Instrumentation的一些进阶基础.比方它注入事件的原理等,但 ...
- Monkey源代码分析番外篇WindowManager如何出的喷射事件的进程间的安全限制
在分析monkey源代码时的一些背景知识不明确,例如看到monkey它是用windowmanager的injectKeyEvent的喷射事件时的方法.我发现自己陷入疙瘩,这种方法不仅能够在当前的应用程 ...
- UiAutomator源代码分析之UiAutomatorBridge框架
上一篇文章<UIAutomator源代码分析之启动和执行>我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程.过程中我们也描写叙述了UiAutomatorB ...
- monkey源代码分析之事件注入方法变化
在上一篇文章<Monkey源代码分析之事件注入>中.我们看到了monkey在注入事件的时候用到了<Monkey源代码分析番外篇之Android注入事件的三种方法比較>中的第一种 ...
- UiAutomator源代码分析之获取控件信息
依据上一篇文章<UiAutomator源代码分析之注入事件>開始时提到的计划,这一篇文章我们要分析的是第二点: 怎样获取控件信息 我们在測试脚本中初始化一个UiObject的时候一般是像下 ...
- Monkey源代码分析番外篇之Android注入事件的三种方法比較
原文:http://www.pocketmagic.net/2012/04/injecting-events-programatically-on-android/#.VEoIoIuUcaV 往下分析 ...
- Monkey源代码分析之事件注入
本系列的上一篇文章<Monkey源代码分析之事件源>中我们描写叙述了monkey是怎么从事件源取得命令.然后将命令转换成事件放到事件队列里面的.可是到如今位置我们还没有了解monkey里面 ...
- 转:SDL2源代码分析
1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...
- 转:RTMPDump源代码分析
0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...
随机推荐
- python手记(47)
#!/usr/bin/env python # -*- coding: utf-8 -*- #http://blog.csdn.net/myhaspl #code:myhaspl@qq.com imp ...
- C#多线程问题整合
一.跨进程访问组件 错误:线程间操作无效: 从不是创建控件“XXX”的线程访问它 解决方法: 1:把CheckForIllegalCrossThreadCalls设置为false 这个方法只是不去捕获 ...
- 云计算分布式大数据神器Spark实战高手之旅
从2012年1月份研究Spark到如今已经两年多的时间了. 在这两年多的时间里比較彻底的研究了Spark的源码并已经在2014年4月24日编写完毕了世界上第一本Spark书籍. 鉴于CSDN在大陆IT ...
- 本地或者服务器同时启动2个或多个tomcat
一,修改配置文件server.xml的端口 C:\apache-tomcat-5.5.23-1\conf\server.xml用记事本什么的打开修改3个地方 第一: <Server port ...
- 学习 easyui 之二:jQuery 的 ready 函数和 easyloader 的加载回调函数
Ready 事件不一定 ready 使用 easyloader 的时候,必须要注意到脚本的加载时机问题,easyloader 会异步加载模块,所以,你使用的模块不一定已经加载了.比如下面的代码. &l ...
- Thinkpad X200 屏幕备案
妈妈蛋,屏幕废物前几天(闪屏->暗->变暗),因此,它只能监视房外 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjk2NTg5MA= ...
- Python学习入门基础教程(learning Python)--3.2 if-else分支语句
if-else分支语句结构的特点是当conditon条件满足时,执行if下的语句块,当condition条件不满足时执行else下的语句块,也就是说根据条件来控制让某些语句执行,某些语句不被执行. i ...
- 使用SharePoint管理中心管理服务
使用SharePoint管理中心管理服务 为了管理服务应用程序.场管理员要么使用管理中心,要么使用PowerShell. 管理服务应用程序页面列出了场上执行的服务.你能够管理他们. 很多服务都有自己的 ...
- 面向服务的体系架构SOA
面向服务的体系架构SOA 序言 在.Net的世界中,一提及SOA,大家想到的应该是Web Service,WCF,还有人或许也会在.NET MVC中的Web API上做上标记,然后泛泛其谈! 的确,微 ...
- 工作经常使用的SQL整理,实战篇(一)
原文:工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...