一、前言
这是第二篇关于客户端性能采集工具的文章,记录工具开发的第二个方法(第一个方法 Android客户端性能采集工具开发)。我也是偶然想到eclipse做Android平台开发的时候会用到DDMS,然后就上网搜了一下资料。果然找到了ddmlib.jar,它是基于socket通信方式完成与adb交互,这样就可以不通过命令行进行数据获取,这次说的第二个方法就是它啦。
基于ddmlib.jar开发的资料还是比较多的,我大概看了一下它的接口说明好像实现也不是很复杂,因此就用Python按照ddmlib.jar的通讯接口进行了造轮子^_^。
二、快速开始
关于adb服务
我们在执行adb devices 或 adb shell 的命令的时候,其实adb会启动服务用来进行通信。我们也可以直接通过adb start-server启动服务,adb kill-server停止服务。
连接至adb服务
adb服务的默认端口是5037,使用TCP协议通讯。以下是简单的连接代码:
sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.TCP_NODELAY, True) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True) sock.connect(("127.0.0.1",5037))
向adb服务发送请求
成功连接后,就可以发生相关的指令进行交互。具体代码如下(注意数据格式):
cmd = "host:track-devices" # 格式为4个字节的长度和命令数据 # full_cmd = "%04X%s"%(len(cmd), cmd) data = format_request_data(cmd) sock.send(data)
读取adb服务返回的数据
发送数据后,adb首先会返回请求的结果,如果4个字节的数据为OKAY表示请求成功。接下来就是请求的数据或者是错误信息。这里返回有两种方式,host:transport请求的数据返回格式为第二种,因此需要特别注意。
data = sock.recv(4) # 返回OKAY表示成功 # 返回数据的格式一 body_len = sock.recv(4) # 返回数据的长度 body_data = sock.recv(body_len) # 数据 # 返回数据的格式二 body_data = sock.recv(size) # util data is ''
三、相关的指令说明
host:track-devices 获得连接的设备列表。返回的内容与adb devices内容是一致的。 host:transport 用于与adb进行命令通讯,这里面可以发送adb shell相关的指令内容。以下就是一个简单获取手机内存的例子:
def c_device_mem(device): """ 获取设备的内存 :return: """ result = service.device_request(device.mAddress, device, "shell:cat /proc/meminfo | grep 'MemTotal'", True) if not result.is_success(): return False ram_data = re.findall(r"d+.+d", result.message) if ram_data: device.mDeviceRom = int(int(ram_data[0]) / 1024) return True
四、后记
ddmlib.jar是Java的库,其实用Java开发会更好,我是简单看了ddmlib中的通讯接口,还算是比较简单,因此决定使用Python来自己搞一下。最后,我也想试试对iOS设备进行通用性能数据采集,最近通过一些资料搜索和对“某个工具”的学习,似乎找到了一个可以实现的方法。大家有兴趣的可以去搜索下关于libimobiledevice库。我后面如果可以搞出来的话,就再介绍给大家。
源自公众号 游戏测试开发