monkey的主要作用是,发送一些随机交互事件模拟人的随机操作。它是如何触发各种事件的呢?
触摸事件包括屏幕以及物理键的触摸,滑动,点击事件。我们可以通过发送一些adb命令模拟这些事件。不过monkey实现时,直接调用hiden api实现。
构造需要的事件,然后调用该接口就能触发了。
activity事件是指我们调用android系统组件的事件。一般测试中,我们也是通过adb shell am命令来实现的。monkey在实现是,是直接通过iactivitymanager实例:
window事件是指操作window的事件,例如转屏。这里直接用iwindowmanager实现。
此外还会调用其他的一些hiden api获取崩溃信息,anr信息等等。这些直接从底层hiden接口拿,比我们上层获取更加方便,准确。
上一节分析到monkey的功能主要分成两块:
产生事件;
触发事件。
因此它的框架设计非常简洁,核心类是monkey.java, monkeyeventsource.java, monkeyevent.java。
核心类
说明
monkey
程序的入口,同时也是调度中心,根据参数选择合适的monkeyeventsource,并适时触发monkeyevent。
monkeyeventsource
monkeyevent的工厂,是一个接口。它有各种实现,例如随机生成monkeyevent,根据配置文件生成monkeyevent,根据网络数据生成monkeyevent等等。
monkeyevent
各种事件的具体实现,是一个抽象类,不同事件有不同实现。在monkey中各种活动都是事件,除了基本的触摸事件,activity事件外,事件之间的停顿也是通过一个monkeythrottleevent来实现。这样概念的扩展,将各种活动一视同仁的对待,使设计变得简单。

如果我们需要扩展monkey的功能,只需要增加自己实现的monkeyeventsource和monkeyevent即可。
我们在terminal中执行adb shell monkey,实际上是执行手机中/system/bin/monkey这个脚本(在源码中也能看到),该脚本具体内容是
所以他是通过/system/bin/app_process运行/system/framework/monkey.jar。
这里需要注意,jvm中的jar文件是一对class文件的zip包。而在android中,可执行文件是dex,所以android里面的jar本质上里面也是dex,直接把eclipse导出的jar包放进去是无法执行的。
这里也有一个小例子(可以在附件中下载完整代码):
我可以看到它成功运行了:
进一步分析该进程,通过ps命令,我们看到该进程是属于shell用户组的,因此它没有root,system那样高的权限,但是比一般的用户进程权限也要高很多,可以多做很多事情,例如静默地安装,卸载。
上述monkey的分析同样适用于uiautomator等android内部的测试工具,更重要的是,我们可以基于这些原理实现我们自己的功能强大,且稳定可靠的测试工具。
<a href="http://blog.csdn.net/edsam49/article/details/11486943">解析android framework下利用app_process来调用java写的命令及示例</a>
<a href="http://blog.csdn.net/luoshengyang/article/details/6768304">android系统进程zygote启动过程的源代码分析</a>
<a href="http://www.cnblogs.com/ruskee/p/5293290.html">有关monkey命令的两个隐藏选项</a>