老李推荐:第6章2节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-获取命令字串

 

从上一节的描述可以知道,MonkeyRunner发送给Monkey的命令是以字符串的形式交互的,那么事件处理的第一步当然是先去获得MonkeyRunner发送过来的字串命令了。

在事件源MonkeySourceNetwork初始化的时候构造函数会创建一个ServerSocket来监听来自客户端的链接和数据,但这个时候客户端并不能真正实现和服务端通信,因为该ServerSocket尚处于阻塞状态。既然ServerSocket是MonkeySourceNetwork的构造函数创建的,那么建立通信的又是哪个方法呢?真正的通信又是什么时候开始建立呢?

这里我们先回答第一个问题,建立通信是由MonkeySourceNetwork的私有成员方法startServer来处理的:

private void startServer()

throws IOException

{

this.clientSocket = this.serverSocket.accept();

...

MonkeySourceNetworkViews.setup();

wake();

this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

this.output = new PrintWriter(this.clientSocket.getOutputStream(), true);

}

代码6-2-1 MonkeySourceNetwork - startServer

  • 572行: 通过调用serverSocket的accept方法来建立一个与客户端连接的Socket通信通道,并把该Socket实例赋予给clientSocket,往下会通过操作这个Socket实例来和客户端交互
  • 581行: 初始化从clientSocket读取数据的BufferedReader实例并赋予给input成员变量,往后的代码只需要调用input的readline方法就能获得一行命令字串数据
  • 583行: 初始化往clientSocket打印输出的PrintWriter实例并赋予给output成员变量,往后的代码只需要调用output的print或者println之类的方法就能往客户端传送数据

回答完第一个问题后,我们跟着看第二个问题,什么时候开始建立通信的?其实这个问题到了现在可以替换成:startServer是谁触发调用的。是从Monkey类的循环执行事件方法runMonkeyCyles调用mEventSource.getNextEvent开始触发的。上一章已经分析过这里的mEventSource是被初始化成MonkeySourceNetwork,因为Monkey是通过MonkeyRunner发送的命令”monkey --port 12345”来启动的。那么我们进入MonkeySourceNetwork的getNextEvent方法:

682   public MonkeyEvent getNextEvent()

683   {

684     if (!this.started) {

685       try {

686         startServer();

687       } catch (IOException e) {

688         Log.e("MonkeyStub", "Got IOException from server", e);

689         return null;

690       }

691       this.started = true;

692     }

...

696     try

697     {

698       for (;;)

699       {

700         MonkeyEvent queuedEvent = this.commandQueue.getNextQueuedEvent();

701         if (queuedEvent != null)

702         {

703           return queuedEvent;

704         }

...

709         if (deferredReturn != null) {

710           Log.d("MonkeyStub", "Waiting for event");

711           MonkeyCommandReturn ret = deferredReturn.waitForEvent();

712           deferredReturn = null;

713           handleReturn(ret);

714         }

715

716         String command = this.input.readLine();

717         if (command == null) {

718           Log.d("MonkeyStub", "Connection dropped.");

719

720

721           command = "done";

722         }

723

724         if ("done".equals(command))

725         {

726           try {

727             stopServer();

728           } catch (IOException e) {

729             Log.e("MonkeyStub", "Got IOException shutting down!", e);

730             return null;

731           }

732

733

734           return new MonkeyNoopEvent();

735         }

736

737

738         if ("quit".equals(command))

739         {

740           Log.d("MonkeyStub", "Quit requested");

741

742           returnOk();

743           return null;

744         }

...

748

749         if (!command.startsWith("#"))

750         {

...

755           translateCommand(command);

756         }

757       }

758

759       return null;

760     }

761     catch (IOException e)

762     {

763       Log.e("MonkeyStub", "Exception: ", e);

764     }

765   }

代码6-2-2 MonkeySourceNetwork - getNextEvent

  • 684-687行: 如果在此之前还没有建立和客户端的通信的话,那么调用startServer方法来建立通信
  • 691行: 把通信状态保存下来。下次调用getNextEvent获取命令字串时就会在684行判断通信是否已经建立,是的话就会使用既有的通信,而不会创建新的Socket通信了
  • 698行: 进入一个无限循环,直到获取到一个事件位置
  • 700-703行: 如果命令队列中还有事件没有处理的话,从命令队列中取得一个事件返回
  • 716行: 通过调用上面提到的input的readline方法获得一个MonkeyRunner客户端发送过来的命令字串
  • 724-728行: 判断如果MonkeyRunner发送过来的命令字串是”done”的话,关闭与客户端的Socket通信
  • 738-744行: 判断如果MonkeyRunner发送过来的命令字串是”quit”的话,直接退出循环
  • 749-756行: 判断如果MonkeyRunner发送过来的命令字串不是上面两种情况,且不是以”#”号开始的话,调用MonkeySourceNetwork的translateCommand来进行往下的命令字串的解析翻译处理工作

老李推荐:第6章2节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-获取命令字串的更多相关文章

  1. 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件

    老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...

  2. 老李推荐:第14章5节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态

    老李推荐:第14章5节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态   poptest是国内唯一 ...

  3. 老李推荐:第14章6节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-启动ViewServer

    老李推荐:第14章6节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-启动ViewServer   poptest是国内唯一一家培养 ...

  4. 老李推荐:第14章3节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-HierarchyViewer实例化

    老李推荐:第14章3节<MonkeyRunner源码剖析> HierarchyViewer实现原理-HierarchyViewer实例化 poptest是国内唯一一家培养测试开发工程师的培 ...

  5. 老李推荐: 第14章2节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-HierarchyViewer架构概述

    老李推荐: 第14章2节<MonkeyRunner源码剖析> HierarchyViewer实现原理-HierarchyViewer架构概述   HierarchyViewer库的引入让M ...

  6. 老李推荐:第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程

    老李推荐:第14章1节<MonkeyRunner源码剖析> HierarchyViewer实现原理-面向控件编程VS面向坐标编程   poptest是国内唯一一家培养测试开发工程师的培训机 ...

  7. 老李推荐:第8章7节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-小结

    老李推荐:第8章7节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-小结   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性 ...

  8. 老李推荐:第8章5节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-运行测试脚本

    老李推荐:第8章5节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-运行测试脚本   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化 ...

  9. 老李推荐:第6章8节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-小结

    老李推荐:第6章8节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-小结   本章我们重点围绕处理网络过来的命令的MonkeySourceNetwork这个事 ...

  10. 老李推荐:第8章1节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-运行环境初始化

    老李推荐:第8章1节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-运行环境初始化   首先大家应该清楚的一点是,MonkeyRunner的运行是牵涉到主机端和目 ...

随机推荐

  1. Bootstrap记录

    左侧 导航下拉: <li class="dropdown"> <a href="#" class="dropdown-toggle& ...

  2. 剑指offer编程题Java实现——面试题11数值的整数次方

    题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...

  3. CSS1,CSS2选择器详解

    第一.CSS1选择器: 1.元素选择器(也叫标签选择器,是最基本的选择器) <style> html{background-color: red;} div{background-colo ...

  4. Linux JDK 的安装卸载

    用root用户登陆到系统,打开一个终端输入 # rpm -qa|grep gcj显示内容其中包含下面两行信息# java-1.4.2-gcj-compat-1.4.2.0-27jpp# java-1. ...

  5. 【2017-02-26】String类、Math类、DateTime类

    一.String类 黑色小扳手 - 属性     后面不带括号紫色立方体 - 方法     后面带括号 字符串.Length  -  字符串长度,返回int类型 字符串.TrimStart() - 去 ...

  6. 解决CenOS 7下启动ActiveMQ时报错

    基于 CentOS 7,ActiveMQ 5.9.1 问题重现 在 CentOS 7 下安装好ActiveMQ后,执行 /usr/local/apache-activemq-5.9.1/bin/act ...

  7. Git基础教程(一)

    本教程为学习笔记,github作为最受欢迎的资源库,不可不学!详细教程参见:廖雪峰的官方网站Git教程系列.准备花两篇幅搞定实战总结,闲言碎语少说,脚踏实地求真! 1,Git入门       Git是 ...

  8. 使用NTP协议服务器时间同步

    NTP是用来使系统和一个精确的时间源保持时间同步的协议.建议大家在自己管理的网络中建立至少一台时间服务器来同步本地时间,这样可以使得在不同的系统上处理和收集日志和管理更加容易.我们分别从windows ...

  9. ceph-deploy install时,远端节点在执行apt-get update命令时失败

    环境 OS:Ubuntu 16.04 背景 使用ceph-deploy部署Ceph集群,调用ceph-deploy install命令在远端节点安装ceph环境,执行apt-get update命令时 ...

  10. JVM学习之类加载

    该文使用Hotspot    JDK1.7 一.类加载器 1.什么是类加载器 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java ...