老李推荐:第6章1节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览
在上一章中我们有简要的介绍了事件源是怎么一回事,但是并没有进行详细的描述。那么往下的这几个小节我们就需要把这方面的知识给补充完整。
这一节我们先主要围绕MonkeySourceNetwork这个事件源来学习事件源的框架结构。首先,要理解事件源,必须先搞清楚几个问题:
- 事件从哪里来?
Monkey的事件来源有多个方面,但是作为MonkeyRunner框架的一部分,它的事件来源主要是来自MonkeyRunner通过网络Socket(USB/TCP协议)发送过来的命令字串。MonkeySourceNetwork这个事件源类就是专门处理这些请求的。MonkeySourceNetwork会在初始化的过程中建立一个ServerSocket来供客户端连接,Socket的端口就是MonkeyRunner通过ADB shell发送给Android目标机器的启动monkey的命令“monkey –port 12345”中的12345。
public MonkeySourceNetwork(int port) throws IOException {
// Only bind this to local host. This means that you can only
// talk to the monkey locally, or though adb port forwarding.
serverSocket = new ServerSocket(port,0, // default backlog
InetAddress.getLocalHost());
}
代码6-1-1 MonkeySourceNetwork - 构造函数
- 来自网络的事件命令字串如何转换成事件?
来自网络的字串是不能直接使用的,Monkey必须把该命令字串进行解析,在必要的时候转换成对应的Monkey事件,这个过程在Monkey中称为命令翻译。MonkeySourceNetwork一旦从MonkeyRunner客户端获取一个字串命令,它就会根据其内部成员COMMAND_MAP这个“字串命令 - 命令翻译类对象”的映射表,检索到该命令字串对应的翻译类对象,然后就会调用它的命令翻译方法来把该字串命令翻译成对应的MonkeyEvent事件,这里说的MonkeyEvent是所有具体事件如MonkeyFlipEvent的父类。以下代码就是COMMAND_MAP在MonkeySourceNetwork类中的实现:
private static final Map<String, MonkeyCommand> COMMAND_MAP = new HashMap<String, MonkeyCommand>();
static {
// Add in all the commands we support
COMMAND_MAP.put("flip", new FlipCommand());
COMMAND_MAP.put("touch", new TouchCommand());
COMMAND_MAP.put("trackball", new TrackballCommand());
COMMAND_MAP.put("key", new KeyCommand());
COMMAND_MAP.put("sleep", new SleepCommand());
COMMAND_MAP.put("wake", new WakeCommand());
COMMAND_MAP.put("tap", new TapCommand());
COMMAND_MAP.put("press", new PressCommand());
COMMAND_MAP.put("type", new TypeCommand());
COMMAND_MAP.put("listvar", new MonkeySourceNetworkVars.ListVarCommand());
COMMAND_MAP.put("getvar", new MonkeySourceNetworkVars.GetVarCommand());
COMMAND_MAP.put("listviews", new MonkeySourceNetworkViews.ListViewsCommand());
COMMAND_MAP.put("queryview", new MonkeySourceNetworkViews.QueryViewCommand());
COMMAND_MAP.put("getrootview", new MonkeySourceNetworkViews.GetRootViewCommand());
COMMAND_MAP.put("getviewswithtext",
new MonkeySourceNetworkViews.GetViewsWithTextCommand());
COMMAND_MAP.put("deferreturn", new DeferReturnCommand());
}
代码6-1-2 MonkeySourceNetwork - COMMAND_MAP
它的键是String类型的字串,代表的是从网络过来的命令字串;它的值是MonkeyCommand的实例,代表的是负责将该命令字串翻译成对应事件的类实例,但要注意的是并不是所有的命令都会生成对应的事件对象并放到事件队列里等待执行,有些命令会在翻译的过程中直接处理返回的。往下描述MonkeyEvent事件的时候会有更详尽的描述。
COMMAND_MAP里面的键记录的只是命令字串,没有包含对应的参数,以下列出Monkey支持的从网络过来的所有命令和对应的参数:
命令字串格式 |
MR是否支持 |
注释 |
touch down x y |
是 |
x代表x坐标,y代表y坐标 |
touch up x y |
是 |
同上 |
touch move x y |
是 |
同上 |
tap x y |
是 |
同上 |
press name |
是 |
Name代表按键名,如"MENU", "HOME", "SEARCH"等 |
key down name |
是 |
同上 |
key up name |
是 |
同上 |
getvar name |
是 |
name 代表属性名 |
listvar |
是 |
|
type line |
是 |
line 代表输入字串 |
wake |
是 |
|
listViews |
是 |
|
queryview |
是 |
|
getRootView |
是 |
|
getViewWithText |
是 |
|
done |
是 |
测试完成,Monkey收到命令后会停止Socket监听 |
quit |
是 |
测试请求退出,Monkey收到后不会停止Socket监听, |
flip open |
否 |
MonkeyRunner不支持发送这两个命令 |
flip close |
否 |
|
trackball dx dy |
否 |
|
deferredReturn |
否 |
这个命令比较特别,做的事情是等待一个命令完成然后执行另外一个命令。但是在MonkeyRunner框架中并没有支持。 |
注: MR代表MonkeyRunner |
表6-1-1 命令字串参照表