天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写《深入理解 MonkeyRunner》书籍“。但因为诸多原因,没有如愿。所以这里把草稿分享出来,所以错误在所难免。有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息。

关于ADB的实现记录。

I. 概览


安卓调试桥(ADB)是用来: 跟踪管理所有连接上或者运行在开发主机上的安卓设备或者模拟器实例。

其实现了各种控制命令(比如: “adb shell”,”adb pull”,等等…)来为各种客户端(命令行用户,或者如DDMS等开发助手之类的程序)提供便利。这些命令其实就是ADB中所谓的“服务”了。

总的来说,所有工作都是在以下各个组件中完成的:

1. ADB服务器


这是一个运行在主机端的后台守护进程。该进程的目的是去感知(监控)USB端口是否有设备挂载或者移除掉,当然也包括对模拟器实例启动和关闭的监控了。

所以它维护了一系列”已连接设备”的信息,并且每个已连接设备都会被赋予以下的一个状态:OFFLINE,BOOTLOADER,RECOVERY或者ONLINE(往后还会有更多其他状态的支持)。

ADB服务器确实可以号称为一个强大的多路路由,它的目的就是像路由一样去协调ADB命令行客户端,服务,和设备之间的数据(事实上是数据包)交换。

2. ADB守护进程(adbd)


“adbd”是作为一个后台守护进程运行在目标安卓设备或者模拟器系统上面的。他的目的是跟主机端的ADB服务器进行连接(真实设备使用USB连接,模拟器通过TCP进行连接)以为运行在主机端的客户端提供一些服务。(译者注: 其实真实机器也可以通过TCP进行连接)

当ADB服务器连接上一个目标设备的adbd守护进程的时候,ADB服务器就会认为该设备是ONLINE状态的。反之,该设备就被认为是OFFLINE状态,代表ADB服务器可以侦查到一个设备/模拟器,但是不能连接上它的adbd守护进程。

BOOTLOADER和RECOVERY状态是和设备是处于引导状态还是修复状态这两个交替状态中的一个相对应的。

3. ADB命令行客户端


‘adb’命令行客户端是用来在一个shell或者脚本中运行adb命令的程序。它首先会尝试定位主机上的ADB服务器,如果发现ADB服务器没有起来的话会尝试把它启动起来。

定位到已经启动的ADB服务器后,该adb命令行客户端就会将它的服务请求命令发送到ADB服务器。它不需要知道ADB服务器处理该服务请求的任何细节。

迄今为止,同一个‘adb‘二进制文件是同时作为ADB服务器和客户端使用的。这样做的好处是让ADB服务器的发布和启动变得更方便。

4. 服务


本质上客户端会跟这里的两种类型的服务进行交互通信。

主机服务:


这些服务完全是运行在ADB服务器内部的,所以根本不需要和任何目标安卓设备进行通信。一个典型的例子就是用来获得一系列当前连接上来主机的设备信息和状态的命令”adb devices”。当然还有不少的一些其他的服务了。

本地服务:


这些服务或许是在目标设备的adbd守护进程内部运行,或许是由adbd启动运行。 ADB服务器在这里扮演的角色就是在运行在客户端和由adbd守护进程运行的服务之间充当一个多路数据流的路由。在这种情况下,ADB服务器会对adbd守护进程和ADB命令行客户端之间的连接进行初始化,然后在他们之间进行数据接力传递。

II. 协议详情


1. 客户端<->服务器端协议


以下是对ADB客户端和ADB服务器自身之间通信所用到的协议的详细描述。ADB服务器监听的TCP端口是localhost:5037。

客户端会使用下面的格式往ADB服务器发送服务请求:

  1. 一个包含指定服务请求数据长度的4字节的16进制字串

  2. 紧跟着该4个字节的就是服务请求数据自身

比如,为了查询ADB服务器的内部版本号,客户端会做以下的动作:

  1. 连接到ADB服务器监听的本地Socket端口tcp:localhost:5037

  2. 发送一个服务请求字串”000Chost:version”到上面对应的Socket

‘host:’这个前缀是用来指示该服务请求是一个主机请求,是一个放松给ADB服务器自身的请求(往下我们会讨论其他的一些类型的请求)。为了方便调试,请求内容长度是以ASCII码的方式进行编码的。

ADB服务器应该用以下格式中的一个对客户端的服务请求进行应答:

  1. 如果服务请求成功,返回一个4字节的”OKAY”字串

  2. 如果服务请求失败的话,返回结果字串的前面是由一个4字节的”FAIL”字串组成,紧跟着该字串后面的是一个代表后面的数据长度的4字节的十六进制数,最后紧跟着的就是描述错误原因的字串内容。

  3. 作为一个例外,对于’host:version’这个服务请求,返回的结果将是一个对应ADB服务器内部版本号的4字节的十六进制字串。

需要注意的是,在服务请求完成,且ADB服务器已经回应了OKAY这个成功代表服务请求成功的应答后,ADB服务器和服务请求客户端之间还是保持在连接状态的,这样就让客户端可以紧接着发送其他的服务请求了。但在一些特别的情况下,ADB服务器的一个OKAY应答将会改变连接的状态。

比方说,以‘host:transport:’这个服务请求为例,这里的’‘的作用是用来标识一个已定的设备/模拟器;在服务请求成功,ADB服务器返回‘OKAY’应答给客户端后,所有客户端紧跟着发送的服务请求都会直接发送到对应设备(由上面服务请求命令中的指定的设备)的adbd守护进程。

文件SERVICES.TXT列出了当前ADB已经实现的所有的服务。

2. 传输模式


一个ADB的传输模式代表的是一个ADB服务器和目标设备或者模拟器之间的连接模型。

  • USB传输模式,应用在物理设备通过使用USB协议连接到主机端的ADB服务器的的情况

  • 本地传输模式, 应用在运行在主机上的模拟器通过TCP协议和ADB服务器连接的情况

理论上来说,编写一个本地传输模式来实现ADB服务器和连接到/运行在另外一台主机的安卓设备/模拟器的连接代理是可行的。但这个现在还没有完成。(译者注: 这份文档google开发人员应该是没有及时更新,因为以4.4.2版本为例,我们是可以通过‘adb connect’命令连接到同一局域网内任意一台设备或者模拟器的)

每个传输模式都可以承载客户端和客户端指向的目标安卓设备/模拟器的一路或者多路数据流。ADB服务器必须合理的处理好该传输模式异常断开的情况(比如,当一个设备被从主机拔掉的情况)。

官方英文版:https://android.googlesource.com/platform/system/core/+/master/adb/OVERVIEW.TXT

——— 未完待续———


作者:天地会珠海分舵 
微信公众号:TechGoGoGo 
微博:http://weibo.com/techgogogo 
CSDN:http://blog.csdn.net/zhubaitian

第4章1节《MonkeyRunner源码剖析》ADB协议及服务: ADB协议概览OVERVIEW.TXT翻译参考(原创)的更多相关文章

  1. 老李推荐:第6章8节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-小结

    老李推荐:第6章8节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-小结   本章我们重点围绕处理网络过来的命令的MonkeySourceNetwork这个事 ...

  2. 老李推荐:第6章7节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-注入按键事件实例

    老李推荐:第6章7节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-注入按键事件实例   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜 ...

  3. 老李推荐:第6章6节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令队列

    老李推荐:第6章6节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-命令队列   事件源在获得字串命令并把它翻译成对应的MonkeyEvent事件后,会把这些 ...

  4. 老李推荐:第6章4节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-翻译命令字串

    老李推荐:第6章4节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-翻译命令字串   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自 ...

  5. 老李推荐:第6章5节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-事件

    老李推荐:第6章5节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-事件   从网络过来的命令字串需要解析翻译出来,有些命令会在翻译好后直接执行然后返回,但有 ...

  6. 老李推荐:第6章3节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令翻译类

    老李推荐:第6章3节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-命令翻译类   每个来自网络的字串命令都需要进行解析执行,只是有些是在解析的过程中直接执行 ...

  7. 老李推荐:第6章2节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-获取命令字串

    老李推荐:第6章2节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-获取命令字串   从上一节的描述可以知道,MonkeyRunner发送给Monkey的命令 ...

  8. 第4章3节《MonkeyRunner源码剖析》ADB协议及服务: ADB协议概览SYNC.TXT翻译参考(原创)

    天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...

  9. 老李推荐:第6章1节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览 2

    事件要到那里去? 每个事件源处理类都维护着一个自己的事件队列, 在Monkey中叫做CommandQueue,里面装的是每个具体的MonkeyEvent事件.当来自网络的字串命令被翻译成对应的Monk ...

随机推荐

  1. BC 2015在百度之星程序设计大赛 - 预赛(1)(矩形区域-旋转卡)

    矩形区域 Accepts: 717 Submissions: 1619 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 ...

  2. c# serialport读取不限数量的16进制数据

    //private char[] HexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', ' ...

  3. Android开发学习总结(五)——Android应用目录结构分析(转)

    一.手动创建android项目 手动创建一个Android项目,命名为HelloWorld,命令如下: android create project -n HelloWorld -t 1 -p E:/ ...

  4. POJ 3579- Median

     Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of n ...

  5. Android使用SVG矢量创建很酷的动态效率!

    尊重原创,欢迎转载.转载请注明: FROM  GA_studio   http://blog.csdn.net/tianjian4592 一个真正酷炫的动效往往让人虎躯一震,话不多说.咱们先瞅瞅效果: ...

  6. Gradle digest

    task类型 copy task copyFiles(type: Copy) { from 'resources' into 'target' include '**/*.xml', '**/*.tx ...

  7. NSIS:获取硬盘中容量最大的分区盘符

    原文 NSIS:获取硬盘中容量最大的分区盘符 我们在安装一些在线视频软件比如迅雷看看时,会发现他们的安装程序会自动判断当前系统中容量最大的分区,以便在其中创建数据缓冲下载的文件夹,这种功能如果实现呢, ...

  8. PLSQL:[1]plsql中文乱码,显示问号

    PLSQL运行sql语句,不识别中文.输出的中文标题显示成问号?? ?? 工具/原料 PLSQL Developer 9 方法/步骤 1 登陆plsql,运行sql语句.输出的中文标题显示成问号??? ...

  9. JAVA连接ACCESS、MYSQL、SQLSEVER、ORACLE数据库

    . 概要 1.1 JDBC概念 JDBC(Java Database Connectivity)是Java语言为了支持SQL功能而提供的与数据库连接的用户的接口.JDBC中包含了一组由(Java)语言 ...

  10. iOS6和iOS7适应代码(6) —— NSLocalizedString

    我们的应用程序都需要国际化,字符串的重要组成部分.一般来说.我们是通过一个string资源文件来达到这个目的,我们需要支持多国语言,有多少次把这个文档本地化.需要使用的代码NSLocalizedStr ...