我們這一節會先去分析下monkeyrunner是如何對參數進行處理的,我們跳轉到MonkeyRunnerOptions這個類里面的processOptions這個方法:
93?? public static MonkeyRunnerOptions processOptions(String[] args)
?94?? {
?95???? int index = 0;
?96
?97???? String hostname = DEFAULT_MONKEY_SERVER_ADDRESS;
?98???? File scriptFile = null;
?99???? int port = DEFAULT_MONKEY_PORT;
100???? String backend = "adb";
101???? Level logLevel = Level.SEVERE;
102
103???? ImmutableList.Builder<File> pluginListBuilder = ImmutableList.builder();
104???? ImmutableList.Builder<String> argumentBuilder = ImmutableList.builder();
105???? while (index < args.length) {
106?????? String argument = args[(index++)];
107
108?????? if ("-s".equals(argument)) {
109???????? if (index == args.length) {
110?????????? printUsage("Missing Server after -s");
111?????????? return null;
112???????? }
113???????? hostname = args[(index++)];
114?????? }
115?????? else if ("-p".equals(argument))
116?????? {
117???????? if (index == args.length) {
118?????????? printUsage("Missing Server port after -p");
119?????????? return null;
120???????? }
121???????? port = Integer.parseInt(args[(index++)]);
122?????? }
123?????? else if ("-v".equals(argument))
124?????? {
125???????? if (index == args.length) {
126?????????? printUsage("Missing Log Level after -v");
127?????????? return null;
128???????? }
129
130???????? logLevel = Level.parse(args[(index++)]);
131?????? } else if ("-be".equals(argument))
132?????? {
133???????? if (index == args.length) {
134?????????? printUsage("Missing backend name after -be");
135?????????? return null;
136???????? }
137???????? backend = args[(index++)];
138?????? } else if ("-plugin".equals(argument))
139?????? {
140???????? if (index == args.length) {
141?????????? printUsage("Missing plugin path after -plugin");
142?????????? return null;
143???????? }
144???????? File plugin = new File(args[(index++)]);
145???????? if (!plugin.exists()) {
146?????????? printUsage("Plugin file doesn't exist");
147?????????? return null;
148???????? }
149
150???????? if (!plugin.canRead()) {
151?????????? printUsage("Can't read plugin file");
152?????????? return null;
153???????? }
154
155???????? pluginListBuilder.add(plugin);
156?????? } else if (!"-u".equals(argument))
157?????? {
158???????? if ((argument.startsWith("-")) && (scriptFile == null))
159???????? {
160
161
162?????????? printUsage("Unrecognized argument: " + argument + ".");
163?????????? return null;
164???????? }
165???????? if (scriptFile == null)
166???????? {
167
168?????????? scriptFile = new File(argument);
169?????????? if (!scriptFile.exists()) {
170???????????? printUsage("Can't open specified script file");
171???????????? return null;
172?????????? }
173?????????? if (!scriptFile.canRead()) {
174???????????? printUsage("Can't open specified script file");
175???????????? return null;
176???????? ??}
177???????? } else {
178?????????? argumentBuilder.add(argument);
179???????? }
180?????? }
181???? }
182
183???? return new MonkeyRunnerOptions(hostname,
port,
scriptFile,
backend,
logLevel,
pluginListBuilder.build(),
argumentBuilder.build());
184?? }
185 }
代碼8-2-2 MonkeyRunnerOptions? - processOptions
?
這里首先請看99-101行的幾個變量初始化,如果用戶在命令行中沒有指定對應的參數,那么這些默認參數就會被使用,我們且看下這些默認值分別是什么:
- hostname:對應‘-s'參數,默認值是'127.0.0.1',也就是本機,將會forward給目標設備運行的monkey,所以加上下面的轉發port等同于目標機器在listen的monkey服務
- port :對應‘-p'參數,默認值是'12345',也就是monkey默認監聽端口
- backend :對應'-be'參數,默認值是‘adb‘,其實往后看代碼我們會發現它也只是支持’adb‘而已。這里需要注意的是這是一個隱藏參數,命令行的help沒有顯示該參數
- logLevel :對應‘-v'參數,默認值'SEVERE',也就是說只打印嚴重的log
代碼往下就是對用戶輸入的參數的解析并保存了,這里要注意幾個隱藏的參數:
- -u :乍一看以為這是一個什么特別的參數,從156-178行可以看到這個參數處理的意義是:當用戶輸入'-u'的時候不會作任何處理,但當用戶輸入的是由‘-’開始的但又不是monkeyrunner聲稱支持的那幾個參數的時候,就會根據不同的情況給用戶報錯。所以這段代碼的意思其實就是在用戶輸入了不支持的參數的時候根據不同的情況給用戶提示而已
- -be :backend,如前所述,只支持‘adb'
- -plugin :這里需要一個背景知識,在google官網有說明,用戶可以通過遵循一定的規范去編寫插件來擴展monkeyrunner的功能,比如在monkeydevice里面按下這個動作是需要通過MonkeyDevice.DOWN這個參數來傳給press這個方法的,如果你覺得這樣子不好,你希望增加個pressDown這樣的方法,里面默認就是用MonkeyDevice.DOWN來驅動MonkeyDevice的press方法,而用戶只需要給出坐標點就可以了,那么你就可以遵循google描述的規范去編寫一個這方面的插件,到時使用的時候就可以通過python方式直接import進來使用了。本書并不會把MonkeyRunner插件進行重點介紹。
在解析出所有的參數之后,processOptions方法最后根據這些參數來初始化MonkeyRunnerOptions類。我們進入到該構造函數看下它究竟做了什么事情:
38?? private MonkeyRunnerOptions(String hostname, int port, File scriptFile, String backend, Level logLevel, Collection<File> plugins, Collection<String> arguments)
?39?? {
?40???? this.hostname = hostname;
?41???? this.port = port;
?42???? this.scriptFile = scriptFile;
?43???? this.backend = backend;
?44???? this.logLevel = logLevel;
?45???? this.plugins = plugins;
?46???? this.arguments = arguments;
?47?? }
代碼8-2-3 MonkeyRunnerOptions - 構造函數
?
所做的事情非常簡單,就是把解析出來的所有參數保存到MonkeyRunnerOptions類的實例里面,今后需要的時候就進去拿就好了。