很多刚开始用 Ubuntu 做安卓开发、刷机或自动化测试的人,都会被同一个问题卡住:电脑上明明装了 ADB,输入adb devices却看不到手机,或者提示unauthorized。网上搜索到的教程大多以 Windows 为背景,到了 Linux 环境下,驱动、USB 权限、授权弹窗的逻辑都变了,照着操作往往越走越偏。
这篇文章就以 Ubuntu 为例,把 ADB 的安装、配置、设备连接、常用命令和常见排错完整串一遍。你会理解为什么在 Ubuntu 上安装 ADB 和 Windows 完全是两套思路,也会掌握一套从零到能正常调试的完整操作路径。读完这篇文章,你不仅能把 ADB 装起来,还能明白它背后 client-server-daemon 的工作方式,以及遇到问题时第一步应该查什么。
1. ADB 到底是什么,为什么 Ubuntu 开发者绕不开它
ADB(Android Debug Bridge,安卓调试桥)是 Android 官方工具链中最基础、也最常用的一个调试工具。它的名字已经说得很形象:桥。桥的一端是电脑,另一端是 Android 设备、模拟器或开发板,中间传输的是调试指令、日志数据、文件信息和屏幕信息。
很多人只把 ADB 理解成“装 APK 工具”,这远远低估了它的价值。在实际开发中,ADB 承担着这些工作:
- 安装、卸载、覆盖安装 APK;
- 查看实时日志(logcat),排查应用崩溃和 ANR;
- 启动 Activity、停止应用、模拟按键和滑动;
- 截屏、录屏、拉取设备文件;
- 查看电池状态、CPU 使用、内存占用;
- 控制多台设备、结合脚本完成自动化测试。
从架构上看,ADB 由三部分组成。电脑端运行的 client(命令行工具 adb),后台运行的 server 进程,以及设备端运行的 adbd 守护进程。当你在终端输入一条 adb 命令,client 会找到 local server,local server 再通过 USB 或网络连接设备上的 adbd,指令就在这三者之间流转。
理解了这套结构,你就会明白为什么 Ubuntu 上安装 ADB 和 Windows 完全不一样。Windows 下连接安卓手机经常要装厂商驱动,否则设备管理器里只有一个带感叹号的未知设备;而 Linux 系统本身对 USB 设备的内核驱动支持已经比较完整,你不需要去下载所谓的“手机驱动”,只需要解决一个问题:当前用户有没有权限访问这个 USB 设备。这就是后面要讲的 udev 规则。
所以我的第一个判断是:在 Ubuntu 上安装 ADB,真正的难点不是“安装”这个动作,而是安装之后的权限配置和设备授权。只要把这条链路走通,后续使用会非常顺手。
2. 安装前准备:确认系统版本、架构与权限
在动手之前,先花一分钟确认环境信息。虽然 ADB 安装步骤在绝大多数 Ubuntu 版本上都能复用,但确认版本可以避免后续出现不明所以的兼容问题。
打开终端,依次执行以下命令:
# 查看 Ubuntu 发行版本信息 lsb_release -a输出结果类似:
Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy再确认系统架构:
uname -m如果输出是x86_64,说明是 64 位 x86 架构;如果是aarch64,说明是 ARM 架构。下载官方 platform-tools 时,选择对应架构的压缩包即可。本文后续步骤以常见的x86_64为例,ARM 架构的系统操作逻辑完全一致,只是下载文件不同。
还需要确认当前用户有sudo权限。安装系统级工具、写入/opt目录、修改 udev 规则都需要 root 权限。如果没有sudo权限,只能把 platform-tools 解压在家目录下使用,这一步不影响 ADB 本身的功能,但会限制一些系统级配置。
最后,建议安装两个基础工具,后面下载和解压都会用到:
sudo apt update sudo apt install -y curl unzip这里要说明一点:apt update并不会升级任何软件,它只是把软件源缓存刷新到最新。如果软件源本身有问题,这一步会直接报错,所以它也是一个很好的环境健康检查手段。
3. 最省事的方式:通过 apt 直接安装 ADB
Ubuntu 官方软件源里提供了 ADB 软件包,这是最省事的安装方式。终端执行:
sudo apt update sudo apt install adb如果你的 Ubuntu 版本较老,提示找不到adb包,可以尝试老一点的包名:
sudo apt install android-tools-adb安装完成后,验证是否成功:
adb --version输出类似:
Android Debug Bridge version 1.0.41 Version 34.0.4-... Installed as /usr/bin/adb到这一步,ADB 已经能用了。但你需要注意一个实际问题:Ubuntu 软件源里的 ADB 版本往往滞后于 Google 官方版本。对于日常的adb install、adb logcat来说,老版本问题不大;但如果你连接的设备系统版本较新,或者需要用一些新引入的调试特性,就可能遇到 device offline、协议不兼容等奇怪问题。
所以我的建议是:
- 只是临时调试一台设备,对版本没有要求,用
apt安装就够了; - 长期做安卓开发、自动化测试,或者需要排查疑难问题时,优先使用官方 platform-tools。
4. 推荐方式:使用 Google 官方 platform-tools 并配置全局环境
既然要用就尽量用官方版本。Google 为 Linux 用户提供了 platform-tools 的独立压缩包,里面包含 adb、fastboot 等核心工具。官方长期维护一个 latest 链接,可以直接下载最新稳定版。
4.1 下载并解压
创建一个用于存放 Android 工具的目录,然后下载压缩包:
sudo mkdir -p /opt/android cd /tmp curl -O https://dl.google.com/android/repository/platform-tools-latest-linux.zip sudo unzip platform-tools-latest-linux.zip -d /opt/android解压后,工具会位于/opt/android/platform-tools目录下。你可以确认一下:
ls /opt/android/platform-tools正常情况下能看到adb、fastboot、e2fsdroid等可执行文件。
如果你没有 sudo 权限,也可以解压到自己的家目录:
cd ~ curl -O https://dl.google.com/android/repository/platform-tools-latest-linux.zip unzip platform-tools-latest-linux.zip这样 adb 就在~/platform-tools下,后续只需要把 PATH 指向这个目录。
4.2 配置 PATH 环境变量
为了让系统在任何目录下都能识别adb命令,需要把工具目录加入 PATH。
以/opt/android/platform-tools为例。编辑当前用户的 shell 配置文件:
# Ubuntu 默认是 bash,编辑 ~/.bashrc # 如果你用的是 zsh,则编辑 ~/.zshrc vim ~/.bashrc在文件末尾添加一行:
export PATH=$PATH:/opt/android/platform-tools保存后让配置生效:
source ~/.bashrc如果你把 platform-tools 解压到了家目录,则把路径换成:
export PATH=$PATH:$HOME/platform-tools验证配置是否生效:
which adb adb --versionwhich adb如果输出/opt/android/platform-tools/adb,说明 PATH 配置成功。这里有一个小细节:很多新手改完.bashrc后不执行source,直接开一个新终端,发现命令还是找不到。新终端理论上会重新加载.bashrc,但如果你使用的是图形界面下打开的终端,且 shell 被配置成登录 shell,加载的可能是.profile,所以最稳妥的做法是改完立即source验证。
4.3 初始化 ADB Server
执行任意 adb 命令时,如果系统检测到 server 没有启动,会自动拉起一个后台进程。也可以手动初始化:
adb start-server看到类似以下输出说明 server 启动成功:
* daemon not running; starting now at tcp:5037 * daemon started successfully5037是 ADB server 的默认端口。如果在同一台机器上跑多个 Android 工具链(比如某些 IDE 自带的 adb 版本),端口冲突或者版本不一致会导致设备列表异常,后面会专门说这个问题。
5. USB 连接设备:开发者选项、udev 规则与授权
安装完 ADB 只是第一步。大多数人第一次卡住,都是在这一步:设备插上电脑,adb devices却什么都看不到。
先来说安卓设备端的设置。打开“设置”,找到“关于手机”(有的系统在“关于设备”里),连续点击“版本号”7 次,系统会提示“您已进入开发者模式”。然后返回设置主菜单,进入“开发者选项”,打开“USB 调试”。
需要注意的是,部分国产 ROM 在开发者选项里还有“USB 安装”和“USB 调试(安全设置)”两个开关,如果只打开了“USB 调试”,安装 APK 或执行某些调试命令时仍然会被拒绝。遇到问题时可以多留意这两个开关。
接下来是 Ubuntu 系统端的权限配置。Linux 对 USB 设备的访问权限有严格管理,普通用户默认无法直接访问手机设备节点,所以需要配置 udev 规则。
先插入手机,执行:
lsusb输出中会有一行描述你的手机,类似:
Bus 003 Device 007: ID 18d1:4ee7 Google Inc. Nexus/Pixel Device这里的18d1就是设备的 vendor ID(厂商 ID),4ee7是 product ID。不同厂商的 ID 不同,需要以实际输出为准。
然后创建 udev 规则文件:
sudo vim /etc/udev/rules.d/51-android.rules写入以下内容:
# 文件路径:/etc/udev/rules.d/51-android.rules # 注意:18d1 只是示例,请替换为 lsusb 里看到的实际厂商 ID SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"这条规则的意思是:当接入一个 USB 设备,且其厂商 ID 匹配18d1时,把该设备的权限设置为0666(所有用户可读写),并将设备组归属于plugdev。这样普通用户就不需要 sudo 也能访问设备。
如果你不想精确匹配某个厂商 ID,可以写一个更宽松的规则,但我个人不建议。最稳妥、最小权限的做法是只放行你实际使用的设备厂商。
保存规则后,重新加载 udev 配置:
sudo udevadm control --reload-rules sudo service udev restart然后重新插拔 USB 线,再执行:
adb devices首次连接时,手机屏幕上会弹出“允许 USB 调试吗”的授权窗口,勾选“始终允许”,点击“允许”。注意一个很隐蔽的坑:如果手机处于息屏状态,或者屏幕已锁定,授权弹窗不会出现,设备状态会一直显示unauthorized。所以插线前先确保手机解锁。
授权成功后,再执行:
adb devices -l输出类似:
List of devices attached A1B2C3D4 device usb:1-1 product:xxx model:XXX device:XXX看到device状态,而不是unauthorized或offline,说明整条链路已经打通,你现在可以正常使用 ADB 了。
6. 常用 ADB 命令实战:从安装 APK 到抓取日志
当设备状态显示为device,接下来就是实战阶段。以下命令覆盖日常开发、测试和问题排查中最常用的场景。
6.1 设备管理
# 查看当前连接的设备 adb devices -l # 重启 adb server,设备异常时优先执行 adb kill-server adb start-server # 等待设备上线,常用于脚本开头 adb wait-for-device # 指定设备执行命令(多设备时必要) adb -s A1B2C3D4 shelladb devices -l会显示设备的型号和传输方式(usb:或tcpip:)。如果同时连接了多台设备,后续所有命令建议都加上-s 序列号,否则 adb 会报“more than one device”。
6.2 应用安装与卸载
# 安装 APK adb install app-debug.apk # 覆盖安装,保留数据和缓存 adb install -r app-debug.apk # 允许降版本安装 adb install -r -d app-debug.apk # 卸载应用 adb uninstall com.example.app参数说明:-r表示 replace,覆盖安装;-d表示允许降级安装。如果遇到INSTALL_FAILED_UPDATE_INCOMPATIBLE,一般是因为签名不一致,或者系统不允许降级,可以尝试卸载后重新安装,但要注意这会清空应用数据。
6.3 查看日志
日志是排查问题的核心手段。
# 实时输出日志,Ctrl + C 停止 adb logcat -v time # 清空旧日志,便于抓取一次完整操作日志 adb logcat -c # 只输出 Error 级别及以上日志 adb logcat *:E # 导出最近 500 行日志,不阻塞终端 adb logcat -d -t 500 > app.log-v time会让日志带上时间戳,建议平时都加上;-c在脚本中常用;-d表示 dump 模式,一次性输出后退出,不会一直阻塞,适合写入 CI 脚本。
6.4 截图、录屏与电池信息
# 截图并保存到手机 adb shell screencap -p /sdcard/screen.png # 拉取到电脑 adb pull /sdcard/screen.png ./screen.png # 录屏 30 秒,Ctrl + C 手动停止 adb shell screenrecord /sdcard/demo.mp4 # 查看电池状态 adb shell dumpsys battery # 开启完整唤醒历史统计 adb shell dumpsys batterystats --enable full-wake-history # 导出耗电统计 adb shell dumpsys batterystats > batterystats.txtbatterystats输出内容非常庞大,通常在分析应用耗电、后台唤醒问题时才会用到。--enable full-wake-history的作用是让系统记录更完整的唤醒历史,抓完数据后可以配合 Battery Historian 等工具做可视化分析。
6.5 模拟点击与按键
在自动化测试场景里,你经常需要模拟用户操作:
# 模拟点击坐标点 (540, 960),坐标单位为像素 adb shell input tap 540 960 # 模拟滑动:从 (540, 1500) 滑到 (540, 300),持续 300 毫秒 adb shell input swipe 540 1500 540 300 300 # 模拟按键:返回键 adb shell input keyevent KEYCODE_BACK # 模拟按键:Home 键 adb shell input keyevent KEYCODE_HOME坐标需要根据设备分辨率调整。可以先截图拉到电脑上查看,确定要点击的位置。
6.6 无线调试(TCP/IP 方式)
如果不想一直插着 USB 线,可以在 USB 连接状态下开启无线调试:
# 让设备在 5555 端口监听 adb tcpip 5555 # 通过 IP 连接设备,确保手机和电脑在同一局域网 adb connect 192.168.1.100:5555 # 断开连接 adb disconnect 192.168.1.100:5555注意:adb tcpip 5555只需要在 USB 连接时执行一次。设备重启后,通常需要重新设置。在公共网络或不可信环境下,不建议开启无线调试,因为这会暴露一个可远程控制的调试端口。
7. 常见问题与排查思路
在实际使用中,你大概率会遇到下面这些问题。按照表格中的排查顺序操作,多数问题都能在几分钟内解决。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| adb: command not found | ADB 未安装或未加入 PATH | 执行which adb和echo $PATH | 重新安装,或把 platform-tools 目录写入~/.bashrc |
| adb devices 什么都看不到 | USB 线仅供电、接口接触不良 | 执行lsusb看系统是否识别到设备 | 换数据线、换 USB 直连口,避免使用前置 USB hub |
| 设备显示 unauthorized | 手机端授权弹窗未确认,或授权被撤销 | 查看手机屏幕是否有授权窗口 | 重新拔插 USB,勾选始终允许;可在开发者选项中撤销授权后重新验证 |
| 设备显示 offline | adb server 版本与设备端不匹配,或连接中断 | 执行adb kill-server后重试 | 重新拔插 USB,重启 adb server,必要时换成官方最新 platform-tools |
| 有多个设备同时显示 | 真机和模拟器同时连接,或有线无线同时连接同一设备 | 执行adb devices -l查看详细信息 | 命令中加-s 序列号;用adb disconnect断开无线连接 |
| 安装 APK 报 INSTALL_FAILED_UPDATE_INCOMPATIBLE | 已安装应用签名不一致或版本降级 | 查看安装命令是否带了 -r -d | 先卸载旧应用,或使用adb install -r -d安装 |
| 无线连接超时 | 手机和电脑不在同一网段,或 5555 端口未开启 | ping 设备 IP;重跑adb tcpip 5555 | 确保同网段;关闭防火墙测试 |
| 脚本报 createfilew 'nul' failed | Windows 下脚本输出重定向使用> NUL,迁移到 Ubuntu 后未修改 | 检查脚本中的重定向路径 | 将 Windows 的> NUL改为 Linux 的> /dev/null |
最后一行单独说几句。很多从 Windows 迁移到 Ubuntu 的朋友会在跑脚本时遇到createfilew 'nul' failed这类报错。原因很简单:Windows 把NUL当成特殊设备,而 Linux 下对应的是/dev/null。一旦脚本里写的是command > NUL,在 Ubuntu 的 bash 中就会被当作普通文件名处理,从而触发异常。迁移脚本时,除了路径分隔符,重定向目标也要一起检查。
8. 最佳实践与自动化建议
ADB 真正发挥威力是在脚本化和自动化场景。下面这些建议,是我在实际使用中认为最重要的几条。
第一,工具链尽量统一。如果你的机器上同时安装了 Android Studio 自带的 adb、apt 安装的 adb,以及官方 platform-tools 的 adb,三个版本容易互相干扰。建议只保留官方 platform-tools,并确保which adb指向同一个目录。
第二,不要给 udev 规则使用过宽的权限。最稳妥的做法是在51-android.rules中精确匹配自己的设备厂商 ID,而不是直接写一个允许所有 USB 设备的规则。最小权限原则在这里同样适用。
第三,调试完设备后,建议关闭“USB 调试”和开发者选项。尤其是个人设备,开启 USB 调试后,一旦连接到不可信的电脑,对方可以执行任意调试命令。安全边界值得多花几秒去守。
第四,在自动化脚本中尽量使用adb wait-for-device和adb -s。前者能避免设备尚未就绪就执行后续命令;后者能避免多设备环境下误操作。
下面给一个可以直接套用的安卓冒烟测试脚本模板:
#!/usr/bin/env bash # 文件路径:scripts/android-smoke-test.sh # 用法:./android-smoke-test.sh build/outputs/apk/debug/app-debug.apk set -e APK_PATH="${1:-build/app-debug.apk}" PACKAGE_NAME="com.example.app" MAIN_ACTIVITY="com.example.app/.MainActivity" # 等待设备上线 adb wait-for-device # 如果应用已安装,先强制停止 adb shell pm list packages | grep "${PACKAGE_NAME}" && adb shell am force-stop "${PACKAGE_NAME}" # 覆盖安装 adb install -r "${APK_PATH}" # 清空日志后启动应用 adb logcat -c adb shell am start -n "${MAIN_ACTIVITY}" # 等待应用启动 sleep 5 # 截图并拉取到本地 adb shell screencap -p /sdcard/smoke.png adb pull /sdcard/smoke.png ./smoke.png # 导出启动过程中的日志 adb logcat -d -t 200 > smoke.log echo "Smoke test finished. Check smoke.png and smoke.log"脚本中的com.example.app和MainActivity需要替换成你自己的包名和入口 Activity。这个脚本在本地可以快速验证一次构建产物能不能正常安装并启动,在 CI 流水线中也可以直接复用。
9. 总结与后续学习方向
回头看一下整篇文章,核心不是“执行几条安装命令”,而是把从安装到可用的完整链路讲清楚:选择合理的安装来源、配置 PATH、处理 USB 设备权限、完成设备授权,最后用命令完成实际调试任务。这四个环节缺一不可,任何一步出问题,adb devices都不会给你想要的结果。
如果你是从 Windows 迁移过来,还需要额外留意脚本中的跨平台差异,比如> NUL与> /dev/null的区别,以及路径分隔符的差异。这些细节平时不起眼,但在自动化场景里会成为第一个拦路虎。
下一步,可以沿着两个方向深入。一是把 adb 和自动化框架结合,比如用adb shell input做 UI 操作,或者接入 Appium、UIAutomator 这类框架完成更复杂的自动化用例;二是研究 adb 之外的工具链,比如 scrcpy 这类基于 adb 的投屏控制工具,以及 fastboot 在刷机场景中的使用。对于安卓开发和测试工程师来说,熟练使用 ADB 是一项基础能力,值得花时间把它彻底打通。
最后留一句最实用的经验:遇到设备连不上,别急着重装软件,先按adb kill-server、重新拔插 USB、查看手机授权弹窗这个顺序走一遍,大多数问题都能解决。把这条路径记下来,比背十条命令更有用。