• 老李推荐:第14章7节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-获取版本号 2


    代码先是发送”LIST”命令到ViewServer列出所有的打开的窗口,然后把每个窗口都保存起来。342行起按照源码的注释解析就是说:从协议版本3以后开始加入了窗口自动更新的功能,但是在此之前,如果用户想要获得一个获得焦点的窗口的话,需要通过显式的创建一个特殊的哈希值为-1的Window实例来完成。怎么知道它的哈希值是-1呢?请看Window类的getfocusedWindow方法:

     

      return new Window(device, "<Focused Window>", -1);  

    }  

    代码14-7-2 Window-getFocusedWindow方法

    然后再看其调用的Window的构造函数和对应的传入参数:

     public Window(IHvDevice device, String title, int hashCode)  

    {  

    this.mHvDevice = device;  

    this.mTitle = title;  

    this.mHashCode = hashCode;  

    this.mClient = null;  

    }  

    代码14-7-3 Window-构造函数

    最终创建的就是一个标题是”<Focused Window>”,哈希值是-1的Window实例。

    通过以上的示例,主要是想说明,ViewServer的版本会影响到代码的不同处理方式,所以我们还是很有必要去看下这些版本信息是如何获得和保存起来的。

    好,那么我们继续分析HierarchyViewer在装备ViewServer时的方法setupViewServer最后一个调用方法DeviceBridge.loadViewServerInfo,这个方法有点长,我们对它分开来分析,先看第1部分:

     260     public static ViewServerInfo loadViewServerInfo(IDevice device) {  

    261         int server = -1;  

    262         int protocol = -1;  

    263         DeviceConnection connection = null;  

    264         try {  

    265             connection = new DeviceConnection(device);  

    266             connection.sendCommand("SERVER"); //$NON-NLS-1$  

    267             String line = connection.getInputStream().readLine();  

    268             if (line != null) {  

    269                 server = Integer.parseInt(line);  

    270             }  

    271         } catch (Exception e) {  

    272             Log.e(TAG, "Unable to get view server version from device " + device);  

    273         } finally {  

    274             if (connection != null) {  

    275                 connection.close();  

    276             }  

    277         }  

        ...  

    }  

    代码14-7-4 DeviceBridge - loadViewServerInfo获取ViewServer版本

    265行显示的代码的第一个重要的部分是去建立一个DeviceConnection的连接,传入的参数依然是ddmlib的Device类的实例:

     

    36     public DeviceConnection(IDevice device) throws IOException {  

    37         mSocketChannel = SocketChannel.open();  

    38         int port = DeviceBridge.getDeviceLocalPort(device);  

    39         if (port == -1) {  

    40             throw new IOException();  

    41         }  

    42         mSocketChannel.connect(new InetSocketAddress("127.0.0.1", port)); //$NON-NLS-1$  

    43         mSocketChannel.socket().setSoTimeout(40000);  

    44     }  

    代码14-7-5 DeviceConnection - 构造函数

    整个代码所做的事情很清晰明了:

    • 创建一个SocketChannel
    • 根据Device实例获得对应的ViewServer本地转发端口号
    • 把SocketChannel连接上本地的ViewServer转发端口

    这里值得提一提的倒是如何根据Device实例获得ViewServer本地转发端口号这个事情。大家还记得第4小节我们说端口转发的时候,最终Device实例和对应的本地转发端口号是保存在DeviceBridge的一个名叫sDevicePortMap的静态成员HashMap里面的。所以这里所做的事情就是去到这个HashMap里面以Device实例为键把端口号这个值取出来而已:

     

    155     public static int getDeviceLocalPort(IDevice device) {  

    156         synchronized (sDevicePortMap) {  

    157             Integer port = sDevicePortMap.get(device);  

    158             if (port != null) {  

    159                 return port;  

    160             }  

    161             Log.e(TAG, "Missing forwarded port for " + device.getSerialNumber());  

    162             return -1;  

    163         }  

    164     }  

    代码14-7-6 DeviceBridge - getDeviceLocalPort

  • 相关阅读:
    MOSS 2010:安装和使用Office Web Apps
    MOSS 2010:Visual Studio 2010开发体验(29)——工作流开发最佳实践(三)
    VS 2010 : 如何开发和部署Outlook 2010插件(Addin)
    MOSS 2010:Visual Studio 2010开发体验(33)——工作流开发最佳实践(五):全局可重用工作流
    《实践与思考》一书的概述和随笔连载说明
    MOSS 2010:Visual Studio 2010开发体验(21)——使用Business Connectivity Service(BCS)集成业务系统
    用于 Web 应用程序项目部署的 Web.config 转换语法 【转载】
    《实践与思考》系列连载(2)—— 第一部分 我们走在.NET的实践征途上 序言
    MOSS 2010:Visual Studio 2010开发体验(16)——客户端对象模型
    “人在旅途”之随想以及旅游指南(travel.msra.cn)简介
  • 原文地址:https://www.cnblogs.com/poptest/p/5103245.html
Copyright © 2020-2023  润新知