第5章2节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动流程概览(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写《深入理解 MonkeyRunner》书籍“。但因为诸多原因,没有如愿。所以这里把草稿分享出来,所以错误在所难免。有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息。

每个应用都会有一个入口方法来供操作系统调用执行,Monkey这个应用的入口方法就是在Monkey.java这个类里面的,也就是说Monkey.java就是整个Monkey应用的入口类。

Monkey作为一个命令行应用,启动的过程中必然会去把命令行参数给解析出来;同时作为一个MonkeyRunner的服务,在启动完成后,很自然就能想到它必然会循环去等待获取主机发过来的命令。这些都不难理解,其实在Monkey从开始启动到准备好循环等待网络命令过来的过程中主要需要涉及以下动作:

  • 运行环境设置: 在monkey这个shell脚本中设置好运行monkey应用需要的环境
  • 命令参数解析: 将启动monkey命令行应用时输入的参数解析出来
  • 获取系统服务引用:既然monkey需要注入事件到系统里面,那么必然是通过系统提供出来的服务来进行注入的,所以在启动过程中会获得需要的系统服务的引用,比如对 WindowManagerService服务的引用
  • 初始化事件源: 一个事件源代表了事件的来源,比如作为MonkeyRunner的一个服务时接收来自网络的由MonkeyRunner发送过来的命令事件,作为一个独立运行的随机压力测试应用时由Monkey自身生成的事件,这些事件的来源都会有相应的类进行处理。所以在Monkey启动的过程中会对这些事件源的类进行初始化,以便往下进入循环等待事件的时候从对应的事件源中获得需要处理的事件
  • 循环等待事件的到来: 启动完成后,Monkey应用就会进入一个循环状态,不停的检测是否有事件需要执行

整个启动的流程都是发生在Monkey这个类里面的,所以本章主要围绕的就是Monkey类的对应的方法来对以上的整个启动流程进行阐述。Monkey类作为Monkey这个jar包的入口类,包含了很多成员变量和成员方法,我们不会,也不需要把所有的都分析到,我们会尽量把要用到的部分都覆盖到就足够了。这里我们先看下Monkey类的类图以及其主要成员变量和成员方法,然后会在今后的小节中结合该类的源码分析来把上面提到的Monkey启动的整个流程给呈现给大家。

图5-2-1 Monkey类图

首先我们先关注该类的一系列成员变量,它们主要指定了事件的来源以及事件注入需要用到的系统服务的引用等,具体的使用我们会在往下的几个小节对他们描述清楚,现在大家现有一个大概的印象就可以了, 以下对关键成员变量进行相应的解析:

  • mAm: 对ActivityManagerService服务的引用,以便往后通过它来进行Activity相关的操作
  • mWm: 对WindowManagerService服务的的引用,以便往后通过它来进行Windown窗口相关的操作
  • mPm: 对PackageManager的引用,以便往后通过它进行Package相关的操作
  • mSeed: 指导monkey产生伪随机事件流的种子数
  • mServerPort: Monkey服务监听的端口号,默认会被初始化成12345,这样运行在主机端的应用如monkeyrunner命令就可以通过该端口和目标机器进行通信了
  • mEventSource: 事件源实例,不同的事件源有不同的类来实现,但它们都统一实现了MonkeyEventSource这个接口。比如来自网络的控件相关的事件源是由MonkeySourceNetworkViews这个类来实现的

然后我们在看Monkey类的关键方法,首先有个入口main方法作为整个Monkey运行的入口,时所有事情发生的开始。然后剩余的那介个方法主要就是去处理整个Monkey启动过程中需要做的事情了。以下对这些关键成员方法进行相应的解析:

  • main: Monkey应用的入口方法,所有事情开始的地方
  • run: 命令运行入口方法。里面做了很多事情,比如调用processOptions去解析命令行参数,初始化事件源,调用runMonkeyCycles去循环获取并执行命令等
  • processOptions: 解析命令行参数
  • getSystemInterfaces: 获得上面的ActivityManager,WindowManager和PackageManager的引用
  • runMonkeyCycles: 循环从事件源的EventQueue里面获取事件命令执行,其中EventQueue是一个事件队列,保存的是将要执行的事件。比如从网络MonkeyRunner过来的命令最终都会保存到该队列里面

当然,虽然Monkey这个入口类是整个服务启动的主要处理控制类,但因为如上所述在启动过程中需要初始化事件源,且在最后启动完成后会循环获取事件来执行,所以整个流程还会涉及到事件源的初始化和事件的执行。下面我们就以monkey作为一个MonkeyRunner的服务而启动的流程作为例子,看下整个过程的一个序列图:

图5-2-2 Monkey服务启动流程序列图

在Monkey服务启动的过程中,MonkeyRunner会首先执行目标设备的安卓系统中的”/system/bin/monkey”这个shell脚本来准备好Monkey的运行环境并指定”/system/framework/monkey.jar”这个jar包以及对应的入口类““com.android.commands.monkey.Monkey” 来开始运行monkey应用;跟着操作系统会找到monkey.jar包里面Monkey这个入口类的入口方法main进行调用;之后就进入前面描述的一系列Monkey类成员方法的调用来完成启动流程;最后在调用成员方法runMonkeyCycles时就进入了一个循环来不停从网络事件源MonkeySourceNetwork来获取MonkeyRunner从主机端发送过来的命令,然后该命令会被翻译成对应的MonkeyEvent事件,并执行对应的事件注入来模拟用户操作以实现测试自动化。

往下的各个小节就会一步步的以这个序列图为基础来向大家阐述清楚整个启动流程,但至于事件源的MonkeyEvent事件的更详细的分析我们会放在下一章进行讲解。?

——— 未完待续———



作者:天地会珠海分舵

微信公众号:TechGoGoGo

微博:http://weibo.com/techgogogo

CSDN:http://blog.csdn.net/zhubaitian

时间: 2024-12-03 11:16:13

第5章2节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动流程概览(原创)的相关文章

第3章2节《MonkeyRunner源码剖析》脚本编写示例: MonkeyDevice API使用示例(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 上一节我们学习了如何通过MonkeyRunner这个类的静态方法waitForConnection来把后台和设备建立好连接,且看到了在建立连接成功后,该方法会返回来一个MonkeyDevice的实例对象.那么这一节我们

第4章1节《MonkeyRunner源码剖析》ADB协议及服务: ADB协议概览OVERVIEW.TXT翻译参考(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 关于ADB的实现记录. I. 概览 安卓调试桥(ADB)是用来: 跟踪管理所有连接上或者运行在开发主机上的安卓设备或者模拟器实例. 其实现了各种控制命令(比如: "adb shell","

第4章3节《MonkeyRunner源码剖析》ADB协议及服务: ADB协议概览SYNC.TXT翻译参考(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 本文档的目的是去文档化一个客户端请求ADB服务器往adbd守护进程发送文件相关的请求.请查看OVERVIEW.TXT文档去查看(ADB服务器和adbd守护进程)相关信息,查看SERVICES.TXT去学习其他更多的可用

第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 在上一节的第一个"增加日记"的示例中,我们并没有看到日记是否真的增加成功了,也就是说当时并没有进行结果比较.其实在MonkeyRunner框架中,测试结果的比较往往都是通过截屏比对来完成的.而截屏比

老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 1

老李推荐: 第8章4节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-启动AndroidDebugBridge 上一节我们看到在启动AndroidDebugBridge的过程中会调用其start方法,而该方法会做2个主要的事情: 715行startAdb:开启AndroidDebugBridge 722-723行:初始化android设备监控并启动DeviceMonitor设备监控线程. 其中第一点我们上一小节已经做了详尽分析了,那么我们往下就去分析下第2点. Dev

老李推荐:第6章5节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-事件

老李推荐:第6章5节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-事件 从网络过来的命令字串需要解析翻译出来,有些命令会在翻译好后直接执行然后返回,但有一大部分命令在翻译后需要转换成对应的事件,然后放入到命令队列里面等待执行.Monkey在取出一个事件执行的时候主要是执行其injectEvent方法来注入事件,而注入事件根据是否需要往系统注入事件分为两种: 需要通过系统服务往系统注入事件:如MonkeyKeyEvent事件会通过系统的InputManager往系

老李推荐:第6章3节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令翻译类

老李推荐:第6章3节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-命令翻译类 每个来自网络的字串命令都需要进行解析执行,只是有些是在解析的过程中直接执行了事,而有些是需要在解析后创建相应的事件类实例并添加到命令队列里面排队执行.负责这部分工作的就是命令翻译类.那么我们往下还是继续在MonkeySourceNetwork这个范畴中MonkeyCommand类是怎么一回事: 图6-3-1 MonkeyCommand族谱 图中间的MonkeyCommand是一个接口,

老李推荐: 第1章1节《MonkeyRunner源码剖析》概述:前言

老李推荐: 第1章1节<MonkeyRunner源码剖析>概述:前言 前言 相信大家做过安卓移动平台UI自动化开发的必然会用过,至少听过MonkeyRunner这个名字.MonkeyRunner是一个针对安卓平台的UI自动化测试框架,这个框架的其中一个但绝不是唯一的优点是支持用当今非常流行和高效的Python语言来进行脚本开发.同时,它相比Instrumentation框架或者基于Instrumentation的自动化测试框架最大的优点之一就是可以跨应用测试. 这本书不会有什么序言或者致谢什么

第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 上一节我们描述了monkey的命令处理入口函数run是如何调用optionProcess方法来解析命令行参数的.启动参数主要时去指导Monkey时怎么运行起来的,但Monkey作为MonkeyRunner框架的一部分,