安卓调试桥 (Android Debug Bridge, adb),是一种可以用来操作手机设备或模拟器的命令行工具。它存在于 sdk/platform-tools
目录下。虽然现在 Android Studio 已经将大部分 ADB 命令以图形化的形式实现了,但是了解一下还是有必要的。
如果记不住命令怎么办?推荐一个可以快速查看 ADB 命令的插件 adb-idea
链接 ADB
有两种方式来启动 ADB,第一种就是直接进入 sdk/platform-tools
目录,在命令行中输入 adb devices
来验证设备是否连接。然而每次进入 platform-tools
目录很麻烦,因此有第二种方法,将 adb 地址写入环境变量,在 macOS 下面可以这样配置:
1 | export PATH=$PATH:<path to Android SDK>/platform-tools |
然后在命令行中输入 source ~/.bash_profile
或者 source ~/.zshrc
来更新配置文件。
现在,可以在任意路径中输入adb device
,如果手机连接了电脑,并且在 开发者选择
中开启了 USB 调试模式
,那么就能看见你所连接的设备序列号了:
1 | ➜ ~ adb devices |
其中,80QBCNP234K3
是设备序列号,device
是设备状态,设备状态有三种:
- offline — 设备未连接到 adb 或者没有响应
- device — 设备已连接到 adb
- no device — 未连接模拟器/设备
安装和卸载
安装
我们可以使用 adb install [option] <path>
命令来将电脑上的一个 APP 安装到手机上,比如:
1 | adb install game.apk |
有时候你电脑上连接的设备不止一个,那么在做一些操作之前,需要指定我们要操作的设备的序列号,也就是需要执行 adb -s [serial_number] command
命令。
比如现在有两部 Android 手机连接了电脑并都打开了开发者模式,那么在安装 game.apk 的时候,命令就需要变一下:
1 | adb -s 80QBCNP234K3 install game.apk |
覆盖安装
如果重复安装一个 APP,那么就会得到一个错误信息:Failure [INSTALL_FAILED_ALREADY_EXISTS]
,这个时候就需要覆盖安装了:加上 -r
(replace) 来替换当前应用:
1 | adb install -r game.apk |
卸载
卸载一个 APP 的命令是 adb uninstall [option] <packagename>
,
1 | adb uninstall com.test.app |
注意: 卸载 APP 时需要使用的是 APP 的包名(package name)。而从电脑安装 APP 到手机上只需要知道电脑中 APK 的文件名。
APP 卸载之后,其缓存文件一般也会被清除。如果我们想保留缓存文件,可以添加 -k
,即:
1 | adb uninstall -k com.test.app |
文件操作
Android 手机中的文件路径
以前,手机的容量比较小的时候,一般都会有 SD 卡扩展,然后就把资源数据存放到 SD 卡目录下,到现在手机容量越来越大,很多手机已经取消了 SD 卡,但是为了做兼容,也会 mock 一个假的 SD 卡路径。因此,现在也有很多开发者将 APP 数据保存在 /sdcard
目录下。现在已经不推荐将文件存储在 /sdcard
目录下了。
当然,音频视频文件还是应该放在 SD 卡目录下。SD 卡的路径是 /mnt/sdcard/
或者 /sdcard
,/sdcard
是 /mnt/sdcard
的软链接。其中,/mnt/sdcard/DCIM
一般用于存放照片的,DCIM 是 Digital Camera IMages
的缩写,但是我们的截图及 APP 保存图片的位置,一般是在 /mnt/sdcard/Pictures
。以此类推,可以知道视频文件存放在 /mnt/sdcard/Movies
等等。
当我们在手机上安装好了一个 APP 之后,相关的文件存放在下面两个地方:
- APP 本身被存放在
/data/app
目录下。 - 文件目录存放在
/data/data/<package name>
目录下,该目录下存放有数据库、SharedPreference 和其他缓存数据。
如果你想把手机中的文件拷贝到电脑中,使用 adb pull <remote> [local]
命令,如果 local
地址为空,则会拷贝到电脑当前目录下:
1 | adb pull /sdcard/game.apk |
如果要把电脑中的文件拷贝到手机里,使用 adb push <local> <remote>
命令:
1 | adb push game.apk /sdcard/data/data |
清除 APP 数据
在开发过程中,经常会遇到这么一种情况:清空 APP 缓存数据,然后进行一些列请求。清空 APP 缓存数据可以使用下面的命令:
1 | adb shell pm clear com.example.packagename |
该命令不仅能清除 APP 的缓存,还能把 APP 的数据给清空。
查看所有 APP 的名称
1 | adb shell pm list packages |
该命令可以查看手机上的 APP 名称。可以在后面加上 -f
,这样还能显示该 APP 的路径
事件输入
input
可以在命令行中使用 adb shell input
向屏幕输入一些信息,比如:
1 | adb shell input text "insert%syour%stext%shere" |
其中,%s
表示空格
也可以使用 adb shell input tap
命令来模拟屏幕点击事件,比如:
1 | adb shell input tap 500 1450 |
该命令表示在屏幕 (500, 1450) 的坐标点上进行一次点击
也可以使用 adb shell input swipe
命令来模拟手势滑动事件,比如:
1 | adb shell input swipe 100 500 100 1450 100 |
该命令表示从屏幕坐标 (100, 500) 开始,滑动到 (100, 1450) 结束,整个过程耗时 100ms。
上面的命令还可以模拟”长按”(Long Press) 操作,也就是两个坐标点相同,耗时超过 500ms
1 | adb shell input swipe 100 500 100 500 500 |
可以使用 adb shell input keyevent
命令来模拟点按实体按钮的命令,比如
1 | adb shell input keyevent 25 |
该命令表示调低音量。这个数字 25 是在 AOSP 源码中的 KeyEvent
类里面定义的一个事件常量。该类定义了将近 300 个事件常量。
am
am (Activity Manager) 命令用来启动一个 APP、启动 Activity、启动广播和服务等等。
启动一个 Activity,最简单的命令可以使用 adb shell am start com.package.name/com.package.name.ActivityName
比如:
1 | adb shell am start qiushui.me.test/qiushui.me.test.MainActivity |
如果启动带有参数,则需要使用 -e
标签,比如有一个 SecondActivity 如下:
1 | class SecondActivity : AppCompatActivity() { |
也就是说,启动 SecondActivity 的话需要传入一个 argus_name 参数,那么在命令行中可以执行如下:
1 | adb shell am start qiushui.me.test/qiushui.me.test.SecondActivity -e argus_name Qiushui |
启动带的参数一般是 Key-Value 形式,这里的 Key 是 argus_name,Value 是 Qiushui。
除了默认启动的 Activity 以外,打开其他的 Activity 时,需要在 AndroidManifest 文件中添加
android:exported="true"
属性。
如果我们要启动一个隐式的 Intent,也就是说我们需要传入 action 等参数,在 ADB 调试桥 中可以得知 Intent 的参数规范,比如 -a
表示 action
,-c
表示 category
,-d
表示 data_uri
,-e
表示添加额外 Key-Value 信息。比如:
1 | am start -a "android.intent.action.VIEW" -d "https://www.google.com" |
上面这个命令会启动一个浏览器打开 https://www.google.com
页面 (如果有多个浏览器,会让用户进行选择) 。
am 也能发送广播和启动服务。比如启动一个广播,一般需要添加一个 -a
:
1 | adb shell am broadcast -a "our.specified.action" |
当然,我们可以在上面的命令后面添加 -e
来添加额外信息。
甚至,我们可以直接让手机重启:
1 | adb shell am broadcast -a android.intent.action.BOOT_COMPLETED |
启动一个服务也是类似的:
1 | adb shell am startservice "qiushui.me.test/qiushui.me.test.MyService" |
事件输出
日志信息
使用 adb logcat
可以显示日志信息,使用 command + C
(Windows 下是 Ctrl + C) 来停止日志输出。
当然,比起原生的 adb logcat
,JakeWharton 大神的 pidcat 显示效果更好:
虽然现在 Android Studio 的日志功能已经非常完善了,但是如果遇到不方便打开 Android Studio 的话,使用命令行也是一种选择。
dumpsys
dumpsys 是一个非常强大的命令,它可以提供非常多的系统信息。可以通过 adb shell service list
来查看 dumpsys 能提供查询信息的服务,常用的有如下几个:
服务名 | 类名 | 功能 |
---|---|---|
activity | ActivityManagerService | AMS相关信息 |
package | PackageManagerService | PMS相关信息 |
window | WindowManagerService | WMS相关信息 |
input | InputManagerService | IMS相关信息 |
power | PowerManagerService | PMS相关信息 |
procstats | ProcessStatsService | 进程统计 |
battery | BatteryService | 电池信息 |
alarm | AlarmManagerService | 闹钟信息 |
meminfo | MemBinder | 内存 |
比如想要查看电池信息,命令行中输入 adb shell dumpsys battery
,可以得到如下信息:
1 | Current Battery Service state: |
如果直接使用 adb shell dumpsys activity
来查看信息的话,会得到非常长的代码,其结构大概如下所示:
1 | ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents) |
从上面的目录结构中可以看出,dumpsys activity
得到的信息可以拆分为以下八个命令所得到的信息和:
1 | dumpsys activity intents |
因此,一般根据所需,选择这八个中的一个命令进行查询。比如查看广播相关的,使用 adb shell dumpsys activity broadcasts
命令,查看界面相关的,使用 adb shell dumpsys activity activities
命令。
当然,这八种信息类型,可以分别用缩略来表示,即 adb shell dumpsys activity a
等同于 adb shell dumpsys activity activities
,adb shell dumpsys activity s
等同于 adb shell dumpsys activity services
等等。这里有两个需要注意的是,providers 的缩略是 prov 以及 permissions 的缩略是 perm
如果还是嫌输出内容太多,我只关心运行的 Activity 结构层次其他的无所谓怎么办?可以使用 grep
命令来过滤:
1 | adb shell dumpsys activity | grep -i 'run' |
这样,得到的信息就非常精炼了:
1 | * ContentProviderRecord{978680e u0 qiushui.me.test/com.android.tools.fd.runtime.InstantRunContentProvider} |
从上面可以得出一些信息:屏幕正在显示的界面是 SecondActivity,然后是 MainActivity。而 NexusLauncherActivity 是处于最底层,其实就是 Launcher。
以 “今日头条” APP 为例,看看如何获取该 APP 的相关信息:
打开今日头条 APP,使用 adb shell dumpsys activity a | grep -i 'run'
命令查看,得到信息如下:
1 | Running activities (most recent first): |
可以知道今日头条的包名为com.ss.android.article.news
。
查看 APP 有哪些进程,使用 adb shell dumpsys activity p com.ss.android.article.news | grep -i 'ProcessRecord' | grep -i 'PID'
,得到信息如下:
1 | PID #7081: ProcessRecord{dd9a2d0 7081:com.ss.android.article.news/u0a157} |
可知一共有 4 个进程。还可知道分别的进程名和 PID 等等。
查看 APP 使用了哪些服务,使用 adb shell dumpsys activity s com.ss.android.article.news | grep -i 'ServiceRecord'
显示结果如下:
1 | * ServiceRecord{885e1bf u0 euid: 0 com.ss.android.article.news/com.ss.android.message.NotifyService} |
可以看到该 APP 使用了阿里云推送 com.taobao.accs.ChannelService
。
比如我想看今日头条的内存使用情况?可以使用 adb shell dumpsys meminfo com.ss.android.article.news
命令,显示结果如下:
1 | Applications Memory Usage (kB): |
给出的内存使用信息非常详细!
关于 dumpsys 的介绍就到这里,dumpsys 的强大可见一斑!
屏幕截图
可以使用 screemcap <filename>
命令来进行手机屏幕截图,比如:
1 | adb shell screencap /sdcard/screen.png |
录制视频
可以使用 screenrecord [options] filename
命令来录制屏幕视频,比如
1 | adb shell screenrecord /sdcard/demo.mp4 |
这个命令适用于 Android 4.4 及以上的设备中。
录制视频也有很多参数选项,比如 --size
用来设置视频大小,--time-limit
用来设置最大录制时长等等。
系统命令
查看进程信息
使用 adb shell ps
命令查看进程信息。通常会在该命令后面添加包名,来查看某个应用程序的进程信息
查看 CPU 使用情况
使用 adb shell top
命令查看系统 CPU 使用情况。
参考资料:ADB 调试桥