在Android开发过程中,通过调用ADB(Android Debug Bridge)命令行与设备进行交互是一项基础且重要的技能,ADB是一个多功能命令行工具,允许开发者与模拟器或连接的Android设备进行通信,执行各种操作如安装应用、调试、文件传输等,本文将详细介绍在Android开发中如何通过代码调用ADB命令行,包括实现方式、注意事项及实际应用场景。

调用ADB命令的基本原理
在Android应用中调用ADB命令,本质上是通过Java的Runtime类或ProcessBuilder类执行系统命令,由于ADB命令通常需要在系统环境中运行(如adb shell),因此调用时需要确保应用具有相应的权限,并且设备已开启USB调试模式,调用流程大致分为以下步骤:
- 检查设备连接状态:确保设备已通过USB连接或网络方式(如无线ADB)与开发机通信。
- 构建命令字符串:根据需求拼接完整的ADB命令,如
adb shell pm list packages。 - 执行命令并获取结果:通过
Runtime.exec()或ProcessBuilder启动进程,捕获命令的输出和错误流。 - 处理返回结果:解析命令执行后的输出,提取所需信息或判断操作是否成功。
实现方式详解
使用Runtime类执行命令
Runtime类提供了exec()方法来执行系统命令,以下是一个简单的示例代码:
try {
Process process = Runtime.getRuntime().exec("adb shell pm list packages");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
Log.d("ADB Output", line);
}
int exitCode = process.waitFor();
Log.d("Exit Code", String.valueOf(exitCode));
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
注意事项:
- 直接拼接命令字符串可能存在安全风险(如命令注入),建议对输入参数进行校验。
- 需要处理
InputStream和ErrorStream,避免子进程阻塞。
使用ProcessBuilder类
ProcessBuilder提供了更灵活的进程管理方式,可以设置工作目录、环境变量等:

try {
ProcessBuilder processBuilder = new ProcessBuilder("adb", "shell", "pm", "list", "packages");
processBuilder.redirectErrorStream(true); // 合并错误流和输出流
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
Log.d("ADB Output", line);
}
int exitCode = process.waitFor();
Log.d("Exit Code", String.valueOf(exitCode));
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
优势:
- 支持命令参数列表形式,避免字符串拼接问题。
- 可通过
environment()方法设置ADB路径等环境变量。
关键参数与命令示例
以下是常用ADB命令及其在代码中的调用方式:
| 功能 | ADB命令示例 | 代码实现片段 |
|---|---|---|
| 安装APK | adb install app.apk |
exec("adb install /path/to/app.apk") |
| 卸载应用 | adb uninstall com.example.app |
exec("adb uninstall com.example.app") |
| 拉取文件 | adb pull /sdcard/file.txt |
exec("adb pull /sdcard/file.txt /local/path") |
| 推送文件 | adb push local.txt /sdcard/ |
exec("adb push local.txt /sdcard/") |
| 查看设备列表 | adb devices |
exec("adb devices") |
| 执行Shell命令 | adb shell pm list packages |
exec("adb shell pm list packages") |
权限与兼容性处理
- 权限问题:Android 6.0以上系统需要动态申请
SYSTEM_ALERT_WINDOW权限才能执行某些Shell命令(如模拟按键)。 - 多设备场景:若连接多台设备,需通过
-s <serial>指定设备ID,如adb -s <serial> shell ...。 - 异步处理:长时间运行的命令(如
logcat)应放在子线程中执行,避免阻塞主线程。
实际应用场景
- 自动化测试:通过ADB命令模拟用户操作(如
adb shell input tap)或检查应用状态。 - 日志监控:实时获取设备日志(
adb logcat)用于调试崩溃问题。 - 批量操作:在CI/CD流程中通过脚本调用ADB命令批量安装或卸载应用。
常见问题与解决方案
-
adb: command not found错误:- 原因:ADB未添加到系统环境变量。
- 解决方案:在代码中指定ADB完整路径(如
/usr/local/bin/adb)或通过ProcessBuilder.environment()设置PATH变量。
-
命令执行无响应:
(图片来源网络,侵删)- 原因:未正确关闭输出流或子进程阻塞。
- 解决方案:确保及时读取
InputStream和ErrorStream,或使用destroy()强制终止进程。
相关问答FAQs
Q1: 为什么在应用中调用ADB命令时提示“权限不足”?
A: Android系统限制第三方应用直接执行高危Shell命令,需确保应用具有android:sharedUserId="android.uid.shell"(需签名一致)或通过su提权(需设备Root),部分命令(如reboot)仅限系统应用执行。
Q2: 如何在代码中获取当前连接的设备列表?
A: 可通过执行adb devices命令解析输出,示例代码如下:
Process process = Runtime.getRuntime().exec("adb devices");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
List<String> devices = new ArrayList<>();
while ((line = reader.readLine()) != null) {
if (line.contains("\t")) {
devices.add(line.split("\t")[0]);
}
}
此方法会返回所有已授权设备的序列号列表,可用于多设备场景下的命令分发。
