解说==system/core/adb/

system/core/adb/

Android Debug Bridge (ADB) 这个命令对于android开发者最熟悉不过了,  他的主要功能就是联上模拟器或者真机进行开发和调试.

而市面上的pc版手机助手应用其实就是调用了这个东东来实现在pc上对手机管理的操作.可见他是android对外的一个最主要途径.

连接方式由两种

1.usb物理数据线连接 (真机链接)

2.TCP/IP连接,也就是网络连接 (模拟器链接)

ADB组成的组件

1. ADB server   (adb)

主要在宿主上提供监测发现usb端口附加或移除和模拟器的启动关闭

2.ADB daemon (adbd)

主要在android设备上提供小量的本地功能服务, 例如调用shell去执行某些命令,这是常驻进程,跟着系统一起启动.

3.ADB command-line client (adb)

主要在宿主上输入命令脚本命令.刚开始的时候不知道1和3组件有什么不同,大家的程序名称都是adb,很昏惑!!??

后来在什么都不连接的情况下(就是宿主上没有连接usb和启动模拟器),在宿主的终端上

输入adb install xxxx.apk

应该大家都熟悉这个命令吧,就是把相关apk包安装上设备上(就是安装android应用的命令)

然后终端会打印

* daemon not running. starting it now on port 5037 *
* daemon started successfully *
error: device not found
- waiting for device -

这个时候,在另外的终端下

输入ps aux|grep adb

然后终端会打印

xxxx      3492  0.0  0.0   4752  1028 pts/2    S+   14:02   0:00 adb install xxxx.apk

xxxx      3493  0.2  0.0  22164  1424 pts/2    Sl+  14:02   0:00 adb -P 5037 fork-server server
xxxx      3503  0.0  0.0   8100   892 pts/1    S+   14:03   0:00 grep --color=auto adb

看到了没有,原来adb自身会fork出另外一个adb进程来的,只是这时的adb是带有特定的参数启动的

所以说其实组件3就是

xxxx      3492  0.0  0.0   4752  1028 pts/2    S+   14:02   0:00 adb install xxxx.apk

组件1就是

xxxx      3493  0.2  0.0  22164  1424 pts/2    Sl+  14:02   0:00 adb -P 5037 fork-server server

同一名称应用程序可能会分身出不同版本的程序功能,确实会给刚刚入门的人带来概念上的昏惑,明明说有两种东西在,却找来找去只有一样东西的感觉,不过这招不要以为只有这个地方才有.在android代码其他地方也使用了(例如是java层上的system进程和android应用进程的创建等等)

简要说一下adb工作的流程

组件3(主机)  -----> 组件1(主机)   <-->   socket文件(主机/设备/模拟器)<--> 组件2 (设备/模拟器)

好了,说了这么多现在开始进入代码分析的环节,在这里用一个简单命令例子进行分析,就是上面提到的adb install [-lrtsd] <file>,这是个应用程序安装的命令。

首先看一下adb程序的main入口代码

system/core/adb/adb.c:1688

这里有ADB_HOST宏的定义,用来编译时分别编译成adb和adbd的程序,在分析代码时,大家首先要有一个c/s的概念,就是client/server,有这个前提下理解起来就容易多了。

其实就是在客户端发adb送预定好的指令,然后服务端adb/adbd接受指令,处理相关指令,然后返回结果的一个c/s的简单过程,把命令的发送和命令的处理通过socket独立起来了。

先来看看client客户端代码的流程是怎样走的

1.输入 adb install <file> 命令

2.adb_commandline()

这里就是adb 命令所有参数解释的地方,这时我们只关心解释install参数,find一下他

1626     if (!strcmp(argv[0], "install")) {
1627         if (argc < 2) return usage();
1628         return install_app(ttype, serial, argc, argv);
1629     }

这里的代码比较简单,直接跳过

3.install_app()

这里就是应用安装的代码,其实这里做了两件事情

第一就是把apk文件推送到设备上

第二就是调用shell命令启动pm命令去安装设备上的apk安装包

看到这,你是不是想说,其实我也可以使用adb push 把文件上传到设备

然后adb shell进入终端,在终端上直接pm命令安装应用,对的就是这个模样,只不过adb install 把这些命令都封装到一个命令里,使用起来方便了很多

先在设备上找个可以放东西的临时地方

1896     static const char *const DATA_DEST = "/data/local/tmp/%s";      这是设备内部存储
1897     static const char *const SD_DEST = "/sdcard/tmp/%s";这是外设存储sd卡

至于选择哪个看有没有 -s 的参数

检查apk包的路径和后缀是否正确

然后到正真传文件的地方do_sync_push()

4.do_sync_push()

adb_connect("sync:")通知adbd做好同步的准备

检查要传送的文件是否存在

把文件读入内存,然后将内存的数据写入了socket里

最后读取socket获取结果是否成功,传送完成了

5.pm_command()

向socket写入”shell:pm“指令,让adbd启动pm命令

这里面有个方法

219 int adb_connect(const char *service)

这里比较重点,是连接服务端获取socket fd,如果adb组件1没有启动,随便在这里一起启动了

详情请看代码,应为全部都是对socket读写的操作,只不过就是写入预先定义好的指令命令

再来看看server服务端代码的流程是怎样走的

提示这里所说的服务端是组建2(adbd),假设真实设备或模拟器已经启动并链接上的

1.跟随android系统一起启动并且是守护进程的adbd

2.adb_main()

后台进程的入口点

3.init_transport_registration()

4.void init_transport_registration(void)

5.transport_registration_func()

6.transport_socket_events()

7.handle_packet()

8.create_local_service_socket()

9.service_to_fd()

10.file_sync_service()

以上都是fd事件注册的大概流程,其实本质就是使用了epoll,它是是Linux内核为处理大批量文件描述符而作了改进的epoll,是Linux下多路复用IO接口select/poll的增强版本,

详情用法不详细说,作用就是检测文件的变化状态而通知对应处理

11.do_recv()

这里就是以上客户端例子中的4.do_sync_push() 真正接收保存apk文件的地方,先会从socket里读数据,然后再写入指定路径上

12.fdevent_loop()

13.fdevent_process()

14.fdevent_plist_dequeue()

以上是fd事件不断处理的无限循环的地方,从队列里拿到事件然后逐个处理

15.fdevent_call_fdfunc()

这里其实调用的就是5.transport_registration_func()

这就是服务端传送文件的流程,至于执行shell pm命令流程与之类似就忽略了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值