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

 

那么现在我们已经获得ViewServer对应本地的转发端口号了,ViewServer也已经在实例化DeviceConnection的时候给连接好了,剩下的就差发命令了。我们继续看下”代码14-7-4 DeviceBridge - loadViewServerInfo获取ViewServer版本”的第2个重要部分:

connection.sendCommand("SERVER");

很明显就是往刚才DeviceConnection建立好的连接到ViewServer的SocketChannel发送”SERVER”这个命令了:

 62     public void sendCommand(String command) throws IOException {  

63         BufferedWriter out = getOutputStream();  

64         out.write(command);  

65         out.newLine();  

66         out.flush();  

67     }  

代码14-7-7 DeviceConnection - sendCommand