前言
adb全称为Android Debug Bridge,译为安卓调试桥。是一个命令行工具,主要用于调试设备。adb.exe放置在/sdk/platform-tools目录下,可对设备进行各种操作,包括安装卸载应用、放置与拉取文件、shell交互等等。熟知adb的命令,对于应用调试与测试非常重要。
1.adb原理
adb是一种c(客户端)-s(服务端)架构的程序,包括三个组件客户端,守护进程(adbd),服务器。详细介绍可参考官方说明。
下面是我对于adb的个人理解,首先要分清楚两个物理设备,输入adb命令的个人电脑,接收adb命令的Android设备,他们的角色分工如下:
- 个人电脑:包含客户端与服务器,客户端就是
adb.exe
,用于开发者交互,服务器是在电脑中的一个后台进程,管理电脑与Android设备的通信。 - Android设备:包含一个做为后台进程运行的守护进程adbd,作用是在设备上运行命令。
接下来再捋清楚两者通信过程:
- 个人电脑中运行adb客户端并启动adb服务器进程,进程端口号为本地TCP端口号5037。
- 电脑中的adb服务器会扫描所有连到电脑上安卓设备的端口号,从5555查找到5585之间的所有奇数号端口,一旦发现adb守护进程adbd便会与设备建立连接。
- Android设备的奇数号端口用于adb连接,偶数号端口用于控制台连接,换句话说就是奇数号端口用于数据传输,偶数号端口用于命令传输。
最后,成功建立连接,开始用命令控制Android设备。
2.adb命令大全
类型 | 命令 | 说明 |
---|---|---|
通用命令 | devices | 所有已连接设备连接 |
– | help | 查看帮助 |
– | version | 查看adb客户端版本号 |
网络 | connect HOST[:PORT] | 通过TCP/IP方式连接设备 |
– | disconnect [[HOST]:PORT] | 断开某个或所有设备的连接 |
– | forward –list | 列出所有转发的端口 |
– | forward [–no-rebind] LOCAL REMOTE | 设备端口转发 |
– | ppp TTY [PARAMETER…] | 通过USB进行点对点连接 |
– | reverse – list | 列出设备的所有反向端口转发 |
– | reverse [–no-rebind] REMOTE LOCAL | 操作反向端口转发 |
文件传输 | push [–sync] LOCAL… REMOTE | 本地文件复制到设备 |
– | pull [-a] REMOTE… LOCAL | 设备文件复制到本地 |
– | sync [all-data-odm-oem-product-system] | 同步文件 |
shell | shell [-e ESCAPE][-n][-Tt][-x] | 远程运行脚本命令 |
– | emu COMMAND | 运行模拟器命令 |
app安装 | install [-lrtsdg] [–instant] PACKAGE | 安装一个程序包 |
– | install-multiple [-lrtsdpg] [–instant] PACKAGE… | 多个apk合成一个包安装 |
– | install-multi-package [-lrtsdpg] [–instant] PACKAGE… | 安装多个程序包 |
– | uninstall [-k] PACKAGE | 卸载应用包 |
调试 | bugreport [PATH] | 将错误报告写入指定的路径 |
– | jdwp | 列出托管JDWP传输的进程的pid |
– | logcat | 查看设备的日志 |
安全 | disable-verity | 在userdebug版本上禁用dm-verity检查 |
– | enable-verity | 在userdebug版本上打开dm-verity检查 |
– | keygen FILE | 生成秘钥 |
脚本 | wait-for[-TRANSPORT]-STATE | 等待设备进入给定状态 |
– | get-state | 获取状态 |
– | get-serialno | 获取序列号 |
– | get-devpath | 获取设备路径 |
– | remount [-R] | 重新挂载文件系统 |
– | reboot [bootloader-recovery] | 重启设备 |
– | sideload OTAPACKAGE | 半加载给定的完整OTA软件包 |
– | root | 以root权限重启adbd守护进程 |
– | unroot | 用无root权限重启adbd守护进程 |
– | usb | 通过USB重启adbd监听 |
– | tcpip PORT | 通过TCP重启adbd监听 |
内部调试 | start-server | 开启adb客户端的服务器 |
– | kill-server | 停止服务器 |
– | reconnect | 主机端强制重连 |
– | reconnect device | 设备端强制重连 |
– | reconnect offline | 重置离线/未经授权的设备以强制重新连接 |
环境变量 | $ADB_TRACE | 以逗号分隔的调试信息列表,用于记录日志 |
– | $ADB_VENDOR_KEYS | 以冒号分隔的键列表(文件或目录) |
– | $ANDROID_SERIAL | 要连接的设备序列号 |
– | $ANDROID_LOG_TAGS | logcat打印的tag |
– | $ADB_LOCAL_TRANSPORT_MAX_PORT | 模拟器最大扫描端口 |
3.general commands:通用命令
3.1 devices
查看当前adb连接的所有设备,可选参数-l
,输出如下信息。
- 序列号
- 连接状态
- offline,设备未连接到 adb 或没有响应
- device,设备现已连接到 adb 服务器
- no device 未连接任何设备
- 设备说明,
-l
选项输出的信息。
>adb devices -l
List of devices attached
1e0aa136 device product:natrium model:MI_5s_Plus device:natrium transport_id:1
- 1
- 2
- 3
3.2 version
查看当前adb的版本号与安装路径。
>adb version
Android Debug Bridge version 1.0.41
Version 29.0.6-6198805
Installed as C:\android\sdk\platform-tools\adb.exe
- 1
- 2
- 3
- 4
3.3 help
帮助文档,可查看adb的所有命令用法。
4.networking:网络
4.1 connect HOST[:PORT] 与disconnect [[HOST]:PORT]
通过TCP/IP的方式连接设备。可通过此命令连接处于同一局域网下的android设备,只要电脑与手机连在同一上Wifi上就能使用此方式连接设备,需要知道手机设备的IP地址。
>adb connect 192.168.0.2
connected to 192.168.0.2:5555
>adb devices
List of devices attached
192.168.0.2:5555 device
- 1
- 2
- 3
- 4
- 5
- 6
当想断开某个设备的Adb连接时,可通过disconnect
命令实现,若不带任何参数,则表示断开所有连接。
>adb disconnect
disconnected everything
>adb devices
List of devices attached
- 1
- 2
- 3
- 4
- 5
小提示:手机可以打开热点让电脑连接,手机热点的默认IP一般是192.168.43.1。
>adb connect 192.168.43.1
* daemon not running; starting now at tcp:5037
* daemon started successfully
connected to 192.168.43.1:5555
>adb devices
List of devices attached
192.168.43.1:5555 device
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4.2 forward –list
列出所有端口转发的socket连接,暂未明白如何使用。
5.文件传输:file transfer
5.1 push [–sync] LOCAL… REMOTE
将本地文件复制至设备中。
- 可选参数sync,当与设备中有同名文件时只复制有新修改的文件
- LOCAL… 本地文件目录,可同时复制多个文件
- REMOTE 设备中放置复制文件的目录
示例如下:
C:\android>adb push D:\test\local.txt D:\test\local2.txt /sdcard/Download
D:\test\local.txt: 1 file pushed, 0 skipped. 0.0 MB/s (3 bytes in 0.028s)
D:\test\local2.txt: 1 file pushed, 0 skipped. 0.0 MB/s (3 bytes in 0.002s)
2 files pushed, 0 skipped. 0.0 MB/s (6 bytes in 0.043s)
C:\android>adb shell
//进入设备sdcard目录
generic_x86_arm:/ $ cd /sdcard/Download/
generic_x86_arm:/sdcard/Download $ ls -l
total 8
-rw-rw—- 1 root sdcard_rw 3 2020-04-11 07:15 local.txt
-rw-rw—- 1 root sdcard_rw 3 2020-04-11 07:15 local2.txt
//查看文件内容
generic_x86_arm:/sdcard/Download $ cat local.txt
abc
//使用–sync参数,只复制有修改的文件
C:\android>adb push –sync D:\test\local.txt D:\test\local2.txt /sdcard/Download
D:\test\local.txt: 0 files pushed, 1 skipped.
D:\test\local2.txt: 1 file pushed, 0 skipped. 0.0 MB/s (5 bytes in 0.007s)
//local.txt被跳过,local2.txt被复制,因为local2有经过修改
1 file pushed, 1 skipped. 0.0 MB/s (5 bytes in 0.032s)
generic_x86_arm:/sdcard/Download $ ls -l
total 8
-rw-rw—- 1 root sdcard_rw 3 2020-04-11 07:15 local.txt
-rw-rw—- 1 root sdcard_rw 5 2020-04-11 07:20 local2.txt //与上面对比修改时间有更新
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
复制整个目录到设备,直接传入文件的路径,文件下的所有内容都会被复制到设备中,包括自身目录。
C:\android>adb push D:\test /sdcard/Movies
D:\test\: 3 files pushed, 0 skipped. 0.0 MB/s (8 bytes in 0.020s)
//查看设备中复制的目录,可以看到test目录也被一起复制进了设备中
generic_x86_arm:/sdcard/Movies/test $ ls -l
total 12
-rw-rw---- 1 root sdcard_rw 3 2020-04-11 15:15 local.txt
-rw-rw---- 1 root sdcard_rw 5 2020-04-11 15:20 local2.txt
drwxrwx--x 2 root sdcard_rw 4096 2020-04-11 15:29 test2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
复制目录下的所有文件到设备指定目录,不复制目录本身,只须在目录后加上一个.
即可
C:\android>adb push D:\test\. /sdcard/Music
D:\test\.\: 3 files pushed, 0 skipped. 0.0 MB/s (8 bytes in 0.031s)
//test目录本身并没有被一起复制进来,只复制test目录下的所有文件
generic_x86_arm:/sdcard/Music $ ls -l
total 12
-rw-rw---- 1 root sdcard_rw 3 2020-04-11 15:15 local.txt
-rw-rw---- 1 root sdcard_rw 5 2020-04-11 15:20 local2.txt
drwxrwx--x 2 root sdcard_rw 4096 2020-04-11 15:41 test2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5.2 pull [-a] REMOTE… LOCAL
从设备中拉取文件到本地。
- 可选参数-a,保留文件的时间戳和模式
- REMOTE… 要拉取的设备文件,可同时摘取多个
- LOCAL 放置设备文件的本地目录
示例:
//同时拉取两个不同目录的文件到本地目录中
C:\android>adb pull /sdcard/Download/local.txt /sdcard/Music/local2.txt D:/test/pull
/sdcard/Download/local.txt: 1 file pulled, 0 skipped. 0.0 MB/s (3 bytes in 0.006s)
/sdcard/Music/local2.txt: 1 file pulled, 0 skipped. 0.0 MB/s (5 bytes in 0.002s)
2 files pulled, 0 skipped. 0.0 MB/s (8 bytes in 0.022s)
//查看本地目录pull中的文件
C:\android>dir D:\test\pullD:\test\pull 的目录
//文件属性时间就是拉取时的时间点
2020/04/11 16:08 3 local.txt
2020/04/11 16:08 5 local2.txt2 个文件 8 字节
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
带参数-a拉取文件,并指定新的文件名
//带参数拉取文件,并指定文件名为local_a
C:\android>adb pull -a /sdcard/Download/local.txt D:\test\pull\local_a.txt
/sdcard/Download/local.txt: 1 file pulled, 0 skipped. 0.0 MB/s (3 bytes in 0.010s)
//查看文件
D:\test\pull>dir
D:\test\pull 的目录
2020/04/11 16:08 3 local.txt
2020/04/11 16:08 5 local2.txt
//local_a的时间还是设备中文件属性时间,即是保留了文件的时间戳
2020/04/11 15:15 3 local_a.txt
3 个文件 11 字节
2 个目录 205,634,908,160 可用字节
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
5.3 sync [all|data|odm|oem|product|system|system_ext|vendor]
同步一个设定好的本地目录到设备中,暂未研究明白如何使用。
6.shell
在设备中远程运行shell命令,会单独用一篇文章来介绍可在shell中运行的android命令。
7.app安装
7.1 install [-lrtsdg] [–instant] PACKAGE
向设备中安装单个应用
- 参数l,前向锁定应用
- 参数r,覆盖安装应用
- 参数t,允许测试应用安装,一般是在as上直接点运行生成的apk
- 参数s,在sdcard上安装应用程序
- 参数d,允许应用降级安装,versioncode低于已安装的应用时可使用
- 参数g,授予应用所有运行时权限
- 参数–instant,作为临时应用安装
示例:
//安装apidemos.apk到设备中
>adb install D:\test\ApiDemos.apk
Performing Streamed Install
Success
//再次安装会报错
Performing Streamed Install
adb: failed to install D:\test\ApiDemos.apk: Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install com.example.android.apis without first uninstalling.]
//加上参数-r可实现覆盖安装
>adb install -r D:\test\ApiDemos.apk
Performing Streamed Install
Success
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
7.1.1 关于参数g是否能跳过应用运行时授权的探究
如果安装时加上参数-g
是否代表着所有运行时权限都被自动获取了,下面用一个打开相机的案例进行测试。
正常安装,没有进行运行时授权,打开相机时会报错,提示程序没有CAMERA权限。
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.android.camera/.Camera } from ProcessRecord{4a11c78 6853:com.andrognito.pinlockviewapp/u0a356} (pid=6853, uid=10356) with revoked permission android.permission.CAMERA
- 1
按下来用adb带-g参数进行安装。
>adb install -r -g D:\test\app-debug.apk
Performing Streamed Install
adb: failed to install D:\test\app-debug.apk: Security exception: You need the android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag
java.lang.SecurityException: You need the android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag
at com.android.server.pm.PackageInstallerService.createSessionInternal(PackageInstallerService.java:624)
at com.android.server.pm.PackageInstallerService.createSession(Package
- 1
- 2
- 3
- 4
- 5
- 6
- 7
安装时会报一个错,提示安全异常,需要另一个权限,android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
,下面把这个权限加到清单文件中再次安装。
>adb install -g D:\test\app-debug.apk
Performing Streamed Install
adb: failed to install D:\test\app-debug.apk: Security exception: You need the android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag
java.lang.SecurityException: You need the android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag
at com.android.server.pm.PackageInstallerService.createSessionInternal(PackageInstallerService.java:624)
at com.android.server.pm.PackageInstallerService.createSession(Package
- 1
- 2
- 3
- 4
- 5
- 6
- 7
依然还是报同样的错误,android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
是一个系统应用才能使用的权限,普通应用是没法获得此权限的,所以除非是系统应用,否则无法用adb install -g
绕过应用运行时权限申请的限制。
7.1.2 直接运行as生成的APK为什么别人无法安装
有一种情况是在开发过程中直接在build里边输出的apk文件发给别人是无法安装的,提示的错误如下:
>adb install -r D:\test\test2\app-debug.apk
Performing Streamed Install
adb: failed to install D:\test\test2\app-debug.apk: Failure [INSTALL_FAILED_TEST_ONLY: installPackageLI]
- 1
- 2
- 3
无法安装的原因在于build中生成的apk是测试专用的,在清单文件的application中多添加了一个属性android:testOnly="true"
,如下图所示:
所以这个应用在别的设备上是无法正常安装的,但可以通过adb添加-t参数进行安装。
>adb install -r -t D:\test\test2\app-debug.apk
Performing Streamed Install
Success
- 1
- 2
- 3
7.2 install-multiple [-lrtsdpg] [–instant] PACKAGE…
安装一个应用分包成的多个apk,适用于将一个完整的apk分成多个子apk一起安装的场景。
7.3 install-multi-package [-lrtsdpg] [–instant] PACKAGE…
一次性同时安装多个不同的apk。
>adb install-multi-package ApiDemos.apk app-debug.apk
adb: failed to create multi-package session
Exception occurred while executing:
java.lang.IllegalArgumentException: Unknown option --multi-packageat com.android.server.pm.PackageManagerShellCommand.makeInstallParams(PackageManagerShellCommand.java:1229)at com.android.server.pm.PackageManagerShellCommand.runInstallCreate(PackageManagerShellCommand.java:273)at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:116)at android.os.ShellCommand.exec(ShellCommand.java:96)at com.android.server.pm.PackageMan
D:\test>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
多应用安装一直报错,暂时未找到原因。
7.4 uninstall [-k] PACKAGE
卸载应用,参数-k表示保留应用的数据(/data/data/)与缓存(/sdcard/Android/包名).
>adb uninstall com.andrognito.pinlockviewapp
Success
- 1
- 2
8.调试debugging
8.1 bugreport [PATH]
抓取设备的运行日志到本地特定的路径中,默认名是bugreport.zip。
关于此工具的详细说明可参考此篇博客:https://blog.csdn.net/createchance/article/details/51954142
//生成日志数据抓取到本地D盘中的test目录
adb bugreport D:/test/
//默认生成的运行日志在设备上的存放目录如下所示
/data/user_de/0/com.android.shell/files/bugreports/bugreport-natrium-OPR1.170623.032-2020-05-17-15-44-12.zip
- 1
- 2
- 3
- 4
8.2 jdwp
列出托管JDWP传输的进程的pid。
JDWP: Java Debug Wire Protocol 的缩写,它定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议,主要用以远程调试JVM。
8.3 logcat
查看设备的日志,与android studio上的logcat工具一样的作用。
可使用logcat –help查看更多的参数。
adb logcat *:E //打印等级为E以上的所有日志
- 1
9.安全 security
9.1 disable-verity
在userdebug版本上禁用dm-verity检查
dm-verity是dm(device mapper)的一个target,是一个虚拟块设备,专门用于文件系统的校验
>adb disable-verity
disable-verity only works for userdebug builds
verity cannot be disabled/enabled - USER build
- 1
- 2
- 3
只能在userdebug版本上使用此命令,android系统编译时可选三种模式
- user(发行版本),adb默认关闭,无法调试,手机不能root
- userdebug(调试版本),认打开adb功能,也能调试
- eng(工程版本),最高权限root
官方详细解释
eng
This is the default flavor. A plain make is the same as make eng.
* Installs modules tagged with: eng, debug, user, and/or development.
* Installs non-APK modules that have no tags specified.
* Installs APKs according to the product definition files, in addition to tagged APKs.
* ro.secure=0
* ro.debuggable=1
* ro.kernel.android.checkjni=1
* adb is enabled by default.
* Setupwizard is optional
user
This is the flavor intended to be the final release bits.
-
Installs modules tagged with user.
-
Installs non-APK modules that have no tags specified.
-
Installs APKs according to the product definition files; tags are ignored for APK modules.
-
ro.secure=1
-
ro.debuggable=0
-
adb is disabled by default.
-
Enable dex pre-optimization for all TARGET projects in default to speed up device first boot-up
userdebug
The same as user, except:
-
Also installs modules tagged with debug.
-
ro.debuggable=1
-
adb is enabled by default.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
9.2 enable-verity
在userdebug版本上重新启用dm-verity检查
9.3 keygen FILE
生成adb公钥/私钥; 存储在FILE中的私钥。
>adb keygen D:/test/a.key
adb I 05-17 16:19:17 8124 2280 auth.cpp:64] generate_key(D:/test/a.key)...
- 1
- 2
会在test目录下生成两个文件,一个是a.key,另一个是a.key.pub
10.脚本 scripting
10.1 wait-for[-TRANSPORT]-STATE…
等待设备进入指定的状态中。
STATE 设备状态
- device, 正常连接设备
- recovery, 设备复写状态
- rescue, 系统救援状态
- sideload, 数据线刷机模式
- bootloader, 系统启动加载器
- disconnect,断开连接状态
TRANSPORT 传输协议
- usb,USB连接
- local, 连接的端口
- any [default=any],任意连接
10.2 get-state
获取连接设备的状态,
- offline离线
- bootloader加载系统
- device在线
>adb get-state
device
- 1
- 2
10.3 get-serialno
获取连接设备的序列号
>adb get-serialno
1d0a2131
- 1
- 2
10.4 get-devpath
获取连接设备的路径
>adb get-devpath
unknown
- 1
- 2
10.5 remount [-R]
重新挂载设备,必须要有root权限才能使用
>adb remount
Not running as root. Try "adb root" first
- 1
- 2
10.6 root/unroot
获取root权限/取消root权限
10.7 reboot [bootloader|recovery|sideload|sideload-auto-reboot]
重启设备,可以选定重启的模式
- bootloader,系统加载器
- recovery,恢复出厂设备
- sideload,线刷模式
- sideload-auto-reboot
10.8 usb/ tcpip PORT
重启设备adbd的监听端口
11.内部调试 internal debugging
11.1 start-server/kill-server
启动adb服务/杀掉adb服务
11.2 reconnect
重新连接设备,可选参数
- device,从设备侧断开连接以强制重新连接
- offline ,重置离线/未经授权的设备以强制重新连接
>adb kill-server
//服务被干掉后,调用adb命令会重新启动服务
>adb devices
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
1d0a2131 offline
//设备是离线状态,进行重连
>adb reconnect
reconnecting 1d0a2131 [offline]
>adb devices
List of devices attached
1d0a2131 device
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
12.环境变量 environment variables
变量名 | 说明 |
---|---|
$ADB_TRACE | 以逗号分隔的调试信息列表,用于记录日志: |
$ADB_VENDOR_KEYS | 以冒号分隔的键列表(文件或目录) |
$ANDROID_SERIAL | 要连接的序列号(请参阅-s) |
$ANDROID_LOG_TAGS | logcat使用的标签(请参阅logcat –help) |
$ADB_LOCAL_TRANSPORT_MAX_PORT | 最大模拟器扫描端口(默认5585,16个emus) |
$ADB_MDNS_AUTO_CONNECT | 逗号分隔的mdns服务列表,以允许自动连接(默认为adb-tls-connect) |
13.通用选项
参数名 | 说明 |
---|---|
-a | 监听所有网络接口,而不仅是本地主机 |
-d | 使用USB设备 |
-e | 使用TCP/IP设备 |
-s SERIAL | 使用特定序列号对应的设备 (覆盖 $ANDROID_SERIAL) |
-t ID | 使用特定tcp id对应的设备 |
-H | 服务端口名 [default=localhost] |
-P | 服务端口号 [default=5037] |
-L SOCKET | 在给定套接字上侦听adb服务器[default = tcp:localhost:5037] |