文章

ADB 与调试工具深度解析——跨平台开发者的 Android 调试利器

面试高频:ADB 的 C/S 架构、无线调试、logcat 过滤、dumpsys 与 bugreport 怎么用,以及热重载失败、ANR/crash 的现场排查思路。

ADB 与调试工具深度解析——跨平台开发者的 Android 调试利器

一句话概括

ADB(Android Debug Bridge)是连接你和 Android 设备的万能桥——它既是设备管理器、又是日志服务器、还是调试通道。框架的 flutter run/react-native run-android 背后都在调它,一旦封装层给不出诊断信息,你就得直接上 ADB。

核心结论:掌握 devices、logcat、forward/reverse、dumpsys、bugreport 这五件套,就能脱离 Android Studio 独立定位绝大多数真机问题。 它不挑框架,Flutter/RN/鸿蒙最终都跑在 Android 上。

核心知识点

1. ADB 架构与连接:C/S 模型

ADB 由三部分组成:你敲的 Client、本机后台的 Server(管理设备通信)、设备上的 adbd(守护进程)。所以它能走 USB,也能走 TCP/IP 远程连设备。

1
2
3
4
5
6
7
8
# macOS 装 platform-tools
brew install android-platform-tools
adb --version

# 设备连不上时,重启 server 能解决八成问题
adb kill-server && adb start-server
adb devices
# 状态:device 正常 / offline 需重启 / unauthorized 手机上点"允许"
1
2
3
4
5
6
7
# Android 11+ 无线调试:先配对再连接(开发者选项→无线调试里给端口)
adb pair 192.168.1.50:37000          # 输入配对码
adb connect 192.168.1.50:39777

# Android 10 及以下:USB 状态下切 TCP,再连 IP
adb tcpip 5555
adb connect 192.168.1.50:5555

// ❌ 多装了一份 platform-tools,两个 adb server 抢 5037 端口,flutter 连不上设备 // ✅ 只留一份 adb,冲突时 adb kill-server 后让框架重新拉起

2. 安装卸载与多设备

1
2
3
4
5
6
adb install -r app.apk          # -r 覆盖安装保留数据
adb install -t app.apk          # -t 允许装 testOnly 的 debug 包
adb uninstall com.example.app   # 卸载
adb uninstall -k com.example.app# 保留数据目录

adb -s emulator-5554 shell ...  # 多设备时用 -s 指定序列号

找不到包名时:adb shell pm list packages | grep 关键词,或从当前界面反查 adb shell dumpsys window | grep mCurrentFocus。

3. logcat:日志过滤是基本功

Android 日志级别(由低到高):V < D < I < W < E < F(还有 A/Assert,极少用)。adb logcat 默认刷全量,必须会过滤。

1
2
3
4
5
adb logcat -c                       # 清历史
adb logcat *:E                     # 只看 Error 及以上
adb logcat -s flutter:V ReactNativeJS:V *:S   # 只看指定 tag,其他静默
adb logcat --pid=$(adb shell pidof com.example.app)  # 按进程过滤
adb logcat -v time > app.txt       # 带时间戳落盘,崩了再搜 FATAL EXCEPTION
1
2
# 抓原生层崩溃与 Flutter 引擎错误
adb logcat -s AndroidRuntime:E DEBUG:E flutter:E *:S

// ❌ 出问题只会 adb logcat 然后被刷屏淹没 // ✅ 按 tag + 级别 + pid 三层过滤,必要时 adb bugreport 拿完整快照

4. forward / reverse:热重载与开发服务器的命脉

adb forward 把宿主机端口映射进设备,adb reverse 反过来把设备请求转到宿主机。RN 的 Metro(8081)、Flutter 的调试通道都靠它。

1
2
adb reverse tcp:8081 tcp:8081   # 让设备访问宿主机的 Metro/DevServer
adb forward  tcp:8081 tcp:8081   # 反向(旧设备/部分场景)

Flutter 热重载失败常因 forward 通道断了(USB 接触不良),表现是 Error connecting to the service protocol。先 adb devices 确认在线,再 kill-server/start-server。

5. dumpsys 与 bugreport:系统级透视

1
2
3
4
5
6
adb shell dumpsys meminfo com.example.app   # 内存:Dalvik/Native/Graphics 分项
adb shell dumpsys activity top              # 当前栈顶 Activity
adb shell dumpsys battery set level 10      # 模拟低电量(测省电逻辑)
adb shell screencap -p > shot.png           # 截屏导到本地
adb shell screenrecord /sdcard/d.mp4        # 录屏(默认 3 分钟)
adb bugreport bug.zip                       # 抓 ANR/crash/内存的完整快照

Flutter 应用看 Graphics 行(Skia/GPU 显存)、RN 看 Native Heap,是判断内存泄漏的首要指标。

6. ANR 与崩溃抓取

ANR 阈值:输入事件 5s 无响应、前台 BroadcastReceiver 10s、前台 Service 20s 未完成。日志里搜 ANR in;未 root 真机直接 adb bugreport,在解压后的 bugreport-*/FS/data/anr/traces.txt 里看主线程堆栈(谁持锁、卡在哪)。

1
2
adb bugreport bug_$(date +%Y%m%d_%H%M%S).zip
unzip bug.zip && find . -name traces.txt -exec cat {} \;

其实你每天都在用

  • flutter run 装不上:直接 adb install build/app/outputs/flutter-apk/app-debug.apk 看详细报错
  • 真机热重载断连:八成是 adb reverse 掉了,重连即可
  • RN 红屏但 Metro 正常:adb reverse tcp:8081 tcp:8081 没建上
  • 线上反馈”偶尔卡死”:dumpsys meminfo 前后对比,看 Native/Graphics 是否只涨不跌
  • 想截图给同事看 bug:adb exec-out screencap -p > bug.png 一行搞定
  • 复现不了的崩溃:adb logcat -v time > full.txt 一直录,复现后搜 FATAL EXCEPTION
  • 低电量逻辑测不了:adb shell dumpsys battery set level 5 模拟

常见误解(FAQ)

❌ 误区一:”无线调试就是 adb connect IP:5555,连不上就是网络问题”

Android 11+ 改了协议:必须先在「无线调试」里拿到配对码走 adb pair,再 adb connect,老设备的 tcpip 5555 直连方式在新系统上已不适用。连不上先看 adb devices 是 unauthorized 还是 offline。

❌ 误区二:”logcat 级别是 4 个”

其实是 V/D/I/W/E/F 六个(外加 A)。面试被问到别数少。*:E 表示”E 及以上(E/F)”,*:S 表示全部静默——后者常配合 -s tag:V 做精确过滤。

❌ 误区三:”ANR 看 logcat 就行”

logcat 只能看到 ANR 被系统记录的瞬间,真正的主线程堆栈在 /data/anr/traces.txt,普通真机读不了,必须 adb bugreport 打包后从里面取。只盯 logcat 会漏掉”谁持锁卡住主线程”的根因。

❌ 误区四:”有了 Flutter/RN 的日志命令就不用学 ADB”

flutter logs 本质就是封装的 adb logcat。一旦遇到原生层崩溃(Java/Kotlin Exception)、GPU 内存、Activity 栈、ANR,框架命令给不出信息,最终还是得回到 adb shell dumpsys 和 bugreport。

一句话总结

ADB 是 Android 调试的「地基」——USB/无线连接、logcat 过滤、forward/reverse 打通热重载、dumpsys 透视系统、bugreport 兜底疑难,五件套练熟,你就不只是”会敲 flutter run“的人,而是能在真机现场独立破案的那一个。

本文由作者按照 CC BY 4.0 进行授权