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

    老李推荐:第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来进行往下的命令字串的解析翻译处理工作
  • 相关阅读:
    MongoDB 学习笔记之 MongoDB导入导出
    快学Scala 第十四课 (读取行,读取字符, 控制台读取)
    MongoDB 学习笔记之 权限管理基础
    MongoDB 学习笔记之 索引
    MongoDB 学习笔记之 游标
    MongoDB 学习笔记之 查询表达式
    MongoDB 学习笔记之 基本CRUD
    MongoDB 学习笔记之 入门安装和配置
    Eclipse设置JVM的内存参数
    cron表达式详解
  • 原文地址:https://www.cnblogs.com/poptest/p/5083208.html
Copyright © 2011-2022 走看看