第6章4节《MonkeyRunner源代码剖析》Monkey原理分析-事件源-事件源概览-翻译命令字串

在第2节中我们看到了MonkeySourceNetwork是怎样从Socket中获取MonkeyRunner发送过来的命令字串的,可是最后怎样将它翻译成事件的代码我们还没有进行分析,由于在那之前我们还没有了解命令翻译类的相关知识。那么经过第3小节对命令翻译类的学习后,我们就能够继续往下分析MonkeySourceNetwork的getNextEvent中是怎样翻译命令字串的了。

我们回看下第2小节,最后在获得命令字串之后调用的是MonkeySourceNetwork类的translateCommand方法:

653   private void translateCommand(String commandLine)
654   {
655     Log.d("MonkeyStub", "translateCommand: " + commandLine);
656     List<String> parts = commandLineSplit(commandLine);
657     if (parts.size() > 0) {
658       MonkeyCommand command = (MonkeyCommand)COMMAND_MAP.get(parts.get(0));
659       if (command != null) {
660         MonkeyCommandReturn ret = command.translateCommand(parts, this.commandQueue);
661         handleReturn(ret);
662       }
663     }
664   }
代码6-4-1 MonkeySourceNetwork - translateCommand

  • 653行: 传进来的參数就是一个命令字串。

    通过” 表3-3-1 命令字串和相应的命令翻译类參照表”我们能够看到一个命令字串假设带有參数的话它的形式可能是这种“type line”

  • 656行: 为了方便使用该命令。通过调用commandLineSplit方法把命令字串转换成一个列表分别把命令。每一个參数都独立保存在列表里面。

    这种方法无非就是依据空格等把命令和參数分解出来。所以就不跟踪进去分析了

  • 658行: 将命令和參数分离分别存放到列表后,依据命令去” 代码3-1-2 MonkeySourceNetwork - COMMAND_MAP”所描写叙述的COMMAND_MAP去查找相应的命令翻译类实例。以上面的”touch x y”命令字串为例,就是依据”type”去COMMAND_MAP中查找,相应的将是这一行:

461         COMMAND_MAP.put("type", new TypeCommand());

也就是说找到的相应的命令翻译类是TypeCommand

  • 660行:调用命令翻译类的translateCommand方法来翻译命令列表,注意这里传进去的參数除了命令字串列表之外另一个MonkeySourceNetwork的成员变量commandQueue,也就是我们一直说的命令队列,传进去的目的就是在解析命令的过程中假设须要创建一个相应事件实例的话,那么创建完后就直接往这个同一个的命令队列里面丢即可了

那么往下我们就看下上面的TypeCommand的translateCommand方法是怎样实现的:

294         public MonkeyCommandReturn translateCommand(List<String> command,
295             CommandQueue queue) {
296             if (command.size() == 2) {
297                 String str = command.get(1);
298 
299                 char[] chars = str.toString().toCharArray();
300 
301                 // Convert the string to an array of KeyEvent's for
302                 // the built in keymap.
303                 KeyCharacterMap keyCharacterMap = KeyCharacterMap.
304                         load(KeyCharacterMap.VIRTUAL_KEYBOARD);
305                 KeyEvent[] events = keyCharacterMap.getEvents(chars);
306 
307                 // enqueue all the events we just got.
308                 for (KeyEvent event : events) {
309                     queue.enqueueEvent(new MonkeyKeyEvent(event));
310                 }
311                 return OK;
312             }
313             return EARG;
314         }
  代码6-4-2 TypeCommand - translateCommand

  • 299-299行: 在命令字串列表中取得type命令的參数line,也就是一大串须要输入的字符串了。然后把该字符串每一个字符拆散开来建立一个字符数组chars,由于以下获得每一个字符相应的系统按键事件KeyEvent的的方法接受的參数就是字符数组
  • 304-305行: KeyCharacterMap的getEvents方法官方的解析是用来依据提供的字符数据流生成一个相应按键事件数组,所以这里的意义就是为输入字串的每一个字符都产生一个按键事件,然后组织成一个按键事件队列返回给events变量。

    这里须要提下的是KeyEvent在Android系统中代表一个按键事件,它内部拥有的每一个按键相应的值以及按键相应的Action如ACTION_DOWN/ACTION_UP等等的定义

  • 308-309行: 依据按键事件创建一个MonkeyKeyEvent实例,并把该事件放到传进来的命令队列里面等待运行

这一小节结合TypeCommand这个命令翻译类我们看到了MonkeySourceNetwork从网络获得一个字串命令后是怎样通过调用自身的translateCommand方法来解析出里面的命令和參数,然后依据命令来查找COMMAND_MAP来获得相应的命令翻译类实例。最后通过命令翻译类的translateCommand来依据命令字串创建相应的MonkeyEvent的并把它增加到命令队列中。

在下一小节我们就去学习下这个MonkeyEvent和命令队列的相关知识。



注:很多其它文章请关注公众号:techgogogo或个人博客http://techgogogo.com。当然,也很欢迎您直接微信(zhubaitian1)勾搭。

本文由天地会珠海分舵原创。转载请自觉,是否投诉维权看心情。





原文地址:https://www.cnblogs.com/mfmdaoyou/p/6973553.html