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