老李推荐:第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. 深度神经网络(DNN)损失函数和激活函数的选择

    在深度神经网络(DNN)反向传播算法(BP)中,我们对DNN的前向反向传播算法的使用做了总结.里面使用的损失函数是均方差,而激活函数是Sigmoid.实际上DNN可以使用的损失函数和激活函数不少.这些 ...

  2. 从源码看集合ArrayList

    可能大家都知道,java中的ArrayList类,是一个泛型集合类,可以存储指定类型的数据集合,也知道可以使用get(index)方法通过索引来获取数据,或者使用for each 遍历输出集合中的内容 ...

  3. Github网站加载不完全,响应超时,如何解决

    Github是一个代码托管平台和开发者社区,开发者可以在Github上创建自己的开源项目并与其他开发者协作编码.毫不夸张地说,高效利用Github是一个优秀的程序员必备的基本素质.可是,有的用户在打开 ...

  4. Angular2 路由问题修复 、求解

    Angular2 提供了比angular1 更为强大的路由功能,但是在具体使用路由过程中,可是出现了很多路由不按照预想的方式执行的问题.为了说明今天的问题,我特地新建了一个测试工程.欢迎交流. 首先介 ...

  5. JS完成页面跳转并传参的方法|附加:循环遍历对象

    此方法只能传递较少参数 方法如下: <a href='page/index.html'>跳转</a> 以上是正常写法,如果要传参按一下写法: <!--参数写在?后面,多个 ...

  6. 业务逻辑 : forex & mlm

    业务逻辑 公司通过mlm的制度和顾客进行签约来收取资金,再把资金给第三方公司进行投资,再把所投资的回报给分配给公司和顾客. 公司的资金来自投资者,公司的营销策略来自mlm的制度,由市场人员来创建mlm ...

  7. 百度编辑器 UEditor第一次加载后台数据失败

    给编辑器赋值的代码: var ue = UE.getEditor('content'); ue.ready(function (){      ue.setContent(data.data.cont ...

  8. Hibernate框架单向多对一关联映射关系

    建立多对一的单向关联关系    Emp.java            private Integer empNo //员工编号            private String empName / ...

  9. 快速排序算法javascript实现

    function quicksort(arr){ function q(start,end){ if(start>=end){return;} var pivot = start, temp = ...

  10. golang中的rpc包用法

    RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...