第14章4节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-端

在初始化HierarchyViewer的实例过程中,HierarchyViewer会调用自己的成员方法setupViewServer来把ViewServer装备好,那么我们这里先看下这个方法:

39private void setupViewServer() { 40DeviceBridge.setupDeviceForward(mDevice); 41if (!DeviceBridge.isViewServerRunning(mDevice)) { 42if (!DeviceBridge.startViewServer(mDevice)) { 43// TODO: Get rid of this delay. 44try { 45Thread.sleep(2000); 46} catch (InterruptedException e) { 47} 48if (!DeviceBridge.startViewServer(mDevice)) { 49Log.e(TAG, "Unable to debug device " + mDevice); 50throw new RuntimeException("Could not connect to the view server"); 51} 52return; 53} 54} 55DeviceBridge.loadViewServerInfo(mDevice); 56}代码14-4-1 HierarchyViewer-setupViewServer

从以上代码中我们可以看到该方法去装备ViewServer主要做的事情有如下几点:

40行:设置本地端口到目标机器端ViewServer监听端口的端口转发

41-54行:确定ViewServer线程是否已经启动,没有的话就启动它。

55行:获取ViewServer的版本以及其支持的协议版本

本小节我们先描述第一点,看HierarchyViewer是如何设置本地端口到目标机器端ViewServer监听端口的端口转发的。在第13章第2小节我们也手动做过这个事情,当时发送的命令是:

adb forward tcp:4939 tcp:4939

那么HierarchyViewer是不是也是通过代码做相同的事情呢?那么我们带着这个疑问来进入深入的代码分析。我们进入setupDeviceForward这个方法:

110/**111* Sets up a just-connected device to work with the view server.112* <p/>113* This starts a port forwarding between a local port and a port on the114* device.115*116* @param device117*/118public static void setupDeviceForward(IDevice device) {119synchronized (sDevicePortMap) {120if (device.getState() == IDevice.DeviceState.ONLINE) {121int localPort = sNextLocalPort++;122try {123device.createForward(localPort, DEFAULT_SERVER_PORT);124sDevicePortMap.put(device, localPort);125} catch (TimeoutException e) {126Log.e(TAG, "Timeout setting up port forwarding for " + device);127} catch (AdbCommandRejectedException e) {128Log.e(TAG, String.format("Adb rejected forward command for device %1$s: %2$s",129device, e.getMessage()));130} catch (IOException e) {131Log.e(TAG, String.format("Failed to create forward for device %1$s: %2$s",132device, e.getMessage()));133}134}135}136}代码14-4-2 DeviceBridge – setupDeviceForward

这个处理端口转发的方法主要分3步走:

第1步:获得本地ViewServer转发端口号

第2步:通过Device类发送adb命令创建本地到ViewServer端口转发

第3步:把本地端口号和对应的设备序列号保存起来以便查找

我们先看第1步,就是121行,这里要注意”sNextLocalPort”这个变量,其实它是个静态变量:

private static int sNextLocalPort = 4939;

代码14-4-3 DeviceBridge – sNextLocalPort

所以代码14-4-2中121行所代表的意思是:

第一个建立的ViewServer端口转发的本地端口是4939

下一个建立的ViewServer端口转发的本地端口是在4939的基础自增加1

注意这里自增加的写法是”sNextLocalPort ++”,如果反过来写成”++sNextLocalPort”, 那么第一个本地端口就会变成4940了,这些都是Java的基本语法了,这里以防我们做测试的没有太多编程经验,所以指出来。

好我们继续分析第2步端口转发相应代码, 这个方法传入的参数就是HierarchyViewer的成员变量mDevice,根据本章第3小节的描述,这个变量是ddmlib中的Device类的一个实例,所以以上调用”device.createForward”方法实际上调用的就是Device的createForward方法:

644@Override 645public void createForward(int localPort, int remotePort) 646throws TimeoutException, AdbCommandRejectedException, IOException { 647AdbHelper.createForward(AndroidDebugBridge.getSocketAddress(), this, 648String.format("tcp:%d", localPort),//$NON-NLS-1$ 649String.format("tcp:%d", remotePort)); //$NON-NLS-1$ 650}代码14-4-3 Device – createForward

像第10章《MonkeyDevice实现原理基础》所描述的那样,Device最终直接调用AdbHelper静态类的createForward方法来设置端口转发:

549public static void createForward(InetSocketAddress adbSockAddr, Device device,550String localPortSpec, String remotePortSpec)551throws TimeoutException, AdbCommandRejectedException, IOException {552 553SocketChannel adbChan = null;554try {555adbChan = SocketChannel.open(adbSockAddr);556adbChan.configureBlocking(false);557 558byte[] request = formAdbRequest(String.format(559"host-serial:%1$s:forward:%2$s;%3$s", //$NON-NLS-1$560device.getSerialNumber(), localPortSpec, remotePortSpec));561 562write(adbChan, request);563 564AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);565if (!resp.okay) {566Log.w("create-forward", "Error creating forward: " + resp.message);567throw new AdbCommandRejectedException(resp.message);568}569} finally {570if (adbChan != null) {571adbChan.close();572}573}574}代码14-4-4 AdbHelper – createForward

formAdbRequest我们在之前已经分析过,做的事情就是组建好ADB协议的命令以待发送给ADB服务器,在我们558行中最终组建好的ADB协议命令将会如下:

“host-serial:xxx:forward:localPortSpec;remotePortSpec”

其中xxx就是代表目标设备的序列号,可以通过”adb devices -l”获得:

可见内心底对旅行是多么的淡漠。

第14章4节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-端

相关文章:

  • 【算法】直接插入排序C语言实现
  • 嵌入式 FAAC1.28 在海思HI3518C/HI3518A平台linux中的编译优化
  • 你感兴趣的文章:

    标签云:

    亚洲高清电影在线, 免费高清电影, 八戒影院夜间, 八戒电影最新大片, 出轨在线电影, 午夜电影院, 在线影院a1166, 在线电影院, 在线观看美剧下载, 日本爱情电影, 日韩高清电影在线, 电影天堂网, 直播盒子app, 聚合直播, 高清美剧, 高清美剧在线观看 EhViewer-E站, E站, E站绿色版, qqmulu.com, qq目录网, qq网站目录,