monkey原理
我们在terminal中执行adb shell monkey,实际上是执行手机中/system/bin/monkey这个脚本(在源码中也能看到),该脚本具体内容是
# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/monkey.jar
trap "" HUP
exec app_process $base/bin com.android.commands.monkey.Monkey $*
所以他是通过/system/bin/app_process运行/system/framework/monkey.jar。
Monkey事件注入机制
Monkey注入系统事件是通过framework层的hidenApi(如:activemanager,inputmanager,windowmanager)获取系统服务。如下:
触摸事件:包括屏幕以及物理键的触摸,滑动,点击事件。
Monkey通过InputManager.getInstance().injectInputEvent(keyEvent, int);构造对应的事件,然后调用该接口执行事件。
Activity事件:是指我们调用Android系统组件的事件。
Monkey通过IActivityManager实例来获取activity的系统服务,从而启动某个activity。
IActivityManager am = ActivityManagerNative.getDefault();
am.startActivity();
Window事件:是指操作Window的事件,例如转屏。
Monkey通过获取IWindowManager实例开启系统窗口服务,并执行窗口事件。
IWindowManager wm = null;
wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
wm..thawRotation();//窗口转屏
Monkey的组织结构
Monkey的核心类是Monkey.java,MonkeyEventSource.java,MonkeyEvent.java。
Monkey中有11种事件,这些事件在MonkeyEventSource中对事件之间的比例进行设置。Monkey事件根据类型比例生成事件队列,循环查找事件。(通过runMonkeyCyles()方法从事件队列中获取事件,MonkeyEvent通过command设计模式将具体的事件(如:MonkeyActivityEvent、MonkeyKeyEvent、MonkeyMotionEvent)通过injectEvent()方法逐一注入到系统中。)
在MonkeyEventSource中,对于事件来源主要有脚本模式、网络模式(monkeyRunner)和默认模式(随机事件)。
因此,如果我们需要扩展Monkey的功能,只需要增加自己实现的MonkeyEventSource和MonkeyEvent即可。