什么是 ADB?
ADB(Android Debug Bridge),中文叫“安卓调试桥”,就像一座桥梁,把你的电脑和 Android 设备(手机、平板、模拟器)连接起来。
你可以通过这座桥,远程控制、调试、管理你的设备,就像拥有一把“万能遥控器”。
ADB 的用途
ADB 是开发者的“瑞士军刀”,常见用途包括:
- 调试应用:远程安装、卸载、调试 App。
- 查看日志:实时获取系统和应用的运行日志。
- 远程控制:在电脑上直接操作手机的命令行。
- 文件传输:在电脑和手机之间互传文件。
- 端口转发:让电脑和手机上的服务互通。
- 进程管理:查看、杀死、调试进程。
常用命令形象解释
1. adb logcat
—— “监听器”
作用:
就像给手机装了一个“窃听器”,你能实时听到手机里各种“说话声”——无论是系统的、应用的,还是崩溃的“惨叫声”。
用法:
adb logcat
场景:
调试 App 时,想知道哪里出错了?用 logcat 一看便知!
2. adb shell
—— “远程遥控器”
作用:
相当于你拿着一把“遥控器”,直接进入手机的“后台控制室”,可以输入各种命令,操作手机的文件、进程、网络等。
用法:
adb shell
场景:
想在手机上创建文件、查看目录、执行脚本?用 shell 就像在本地操作电脑一样方便。
3. adb jdwp
—— “侦探名单”
作用:
这是一个“侦探名单”,列出当前手机上所有可以被调试的进程(即支持 JDWP 协议的进程)的 PID(进程号)。
用法:
adb jdwp
场景:
你想 attach(附加)调试器到某个 App?先用这个命令查出它的 PID,再用调试工具连接。
总结
- ADB 就像一座桥,让你用电脑“遥控”手机。
- logcat 是“监听器”,帮你捕捉一切日志。
- shell 是“遥控器”,让你随心所欲操作手机。
- jdwp 是“侦探名单”,帮你找到可以调试的目标。
下面为你介绍一些 ADB 的“隐藏技能”和常用命令的高级用法案例,让你玩转 Android 调试!
1. 端口转发(Port Forwarding)
场景:
你在手机上跑了一个本地 Web 服务(比如调试 WebView 或本地 API),想让电脑直接访问。
命令:
adb forward tcp:6000 tcp:8080
解释:
把电脑的 6000 端口转发到手机的 8080 端口。
现在你在电脑访问 localhost:6000
,其实就是访问手机的 8080 端口。
2. 反向端口转发(Reverse Forwarding)
场景:
手机上的 App 需要访问电脑上的本地服务(如本地开发的 API),但手机和电脑不在同一局域网。
命令:
adb reverse tcp:8081 tcp:8081
解释:
让手机访问自己的 8081 端口时,其实是访问电脑的 8081 端口。
常用于 React Native、Flutter 热重载等场景。
3. 截屏和录屏
截屏:
adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png
录屏:
adb shell screenrecord /sdcard/demo.mp4
adb pull /sdcard/demo.mp4
解释:
先在手机上截屏/录屏,再拉到电脑上。
4. 模拟按键和输入
模拟 HOME 键:
adb shell input keyevent 3
模拟输入文本:
adb shell input text "Hello%sworld"
(注意空格要用 %s
)
5. 安装/卸载/升级 App
安装 APK:
adb install myapp.apk
覆盖安装(升级):
adb install -r myapp.apk
卸载 App:
adb uninstall com.example.app
6. 过滤 logcat 日志
只看某个包的日志:
adb logcat | grep com.example.app
只看错误日志:
adb logcat *:E
只看特定 tag:
adb logcat MyTag:D *:S
7. 远程调试 WebView
命令:
adb forward tcp:9222 localabstract:webview_devtools_remote_进程号
解释:
让 Chrome DevTools 远程调试手机上的 WebView。
8. 直接拉取/推送文件
拉取文件到电脑:
adb pull /sdcard/Download/file.txt
推送文件到手机:
adb push myfile.txt /sdcard/Download/
9. 重启到特定模式
重启到 recovery:
adb reboot recovery
重启到 bootloader:
adb reboot bootloader
10. 一条命令重启 App
杀死并重启 App:
adb shell am force-stop com.example.app
adb shell monkey -p com.example.app -c android.intent.category.LAUNCHER 1
解释:
先强制停止,再用 monkey 启动。
11. 远程调试 JDWP 进程
查找进程 PID:
adb jdwp
端口转发到本地调试器:
adb forward tcp:8700 jdwp:<pid>
用 jdb 连接:
jdb -attach localhost:8700
12. 直接执行 App 的 Activity/Service/Broadcast
启动 Activity:
adb shell am start -n com.example.app/.MainActivity
启动 Service:
adb shell am startservice -n com.example.app/.MyService
发送广播:
adb shell am broadcast -a com.example.app.ACTION_TEST
13. 模拟地理位置
设置经纬度(需要开发者选项允许模拟位置):
adb shell am startservice -a com.google.android.location.internal.EXTRA_LOCATION --es latitude 39.9 --es longitude 116.3
14. 查看当前界面层级(UI Automator)
导出当前界面 XML:
adb shell uiautomator dump
adb pull /sdcard/window_dump.xml
15. 远程调试多设备
指定设备:
adb devices
adb -s <device_serial> shell
16. 录制 bugreport
生成 bugreport:
adb bugreport > bugreport.zip
解释:
收集系统日志、崩溃信息、ANR 等,便于排查复杂问题。
我们以一个常用命令为例,详细讲解它的原理和底层实现。
比如:adb shell am start -n com.example.app/.MainActivity
1. 命令表面作用
这个命令的作用是:
让 Android 设备启动 com.example.app 这个应用的 MainActivity。
2. 命令分解
adb shell
:让你在设备上执行 shell 命令。am
:Activity Manager 的命令行工具,管理四大组件(Activity、Service、Broadcast、ContentProvider)。start
:表示启动一个 Activity。-n com.example.app/.MainActivity
:指定要启动的组件(包名/类名)。
3. 原理流程
步骤一:adb shell
- 你的电脑通过 USB(或网络)和手机建立 ADB 通道。
adb shell
把你输入的命令传到手机的 shell(通常是 sh 或 toybox/sh)。
步骤二:am start
am
是/system/bin/am
,其实是一个 Java 程序(AndroidCommands)。am start
解析参数,最终会调用 Android 的 ActivityManagerService(AMS)。
步骤三:AMS 处理
- AMS 是系统服务,负责管理所有 Activity 的启动、切换、调度。
- AMS 收到“启动 Activity”请求后,会查找目标应用的包名和 Activity 类名。
- 如果应用进程没启动,AMS 会通过 Zygote fork 一个新进程,并加载应用代码。
- AMS 通过 Binder 通信,把启动 Activity 的消息发给应用进程的 ActivityThread。
步骤四:ActivityThread
- ActivityThread 是应用进程的主线程(UI 线程)。
- 它收到“启动 Activity”消息后,反射创建 MainActivity 实例,并调用其生命周期方法(onCreate、onStart、onResume)。
4. 底层实现细节
- am 命令本质上是调用
android.app.ActivityManager
的接口。 - 通过 Binder IPC(进程间通信)把命令从 shell 进程传递到 system_server 进程(AMS 所在)。
- AMS 负责调度应用进程、管理任务栈、处理权限等。
- 启动新进程时,system_server 通过 socket 通信通知 Zygote 进程 fork 子进程。
- 应用进程启动后,ActivityThread 通过 Handler 机制分发消息,最终反射调用 Activity 的构造函数和生命周期。
5. 相关源码位置
frameworks/base/cmds/am/
:am 命令的实现frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
:AMS 实现frameworks/base/core/java/android/app/ActivityThread.java
:应用主线程实现frameworks/base/core/java/android/app/Instrumentation.java
:Activity 启动的具体实现
6. 总结
- 你输入命令 → 电脑通过 ADB 传到手机 → shell 进程执行 am → am 通过 Binder 调用 AMS → AMS 调度应用进程 → ActivityThread 启动 Activity。
- 这背后涉及 ADB 通道、shell 解析、Binder IPC、Zygote 进程管理、Activity 生命周期等多个 Android 核心机制。