在Java程序中执行adb(Android Debug Bridge)命令是一种常见的操作,主要用于自动化测试、设备管理或调试Android应用,实现这一功能的核心思路是通过Java的Runtime类或ProcessBuilder类来启动一个新的进程,该进程执行adb命令并返回结果,以下是详细的实现方法和注意事项。

使用Runtime类执行adb命令是最直接的方式,通过Runtime.getRuntime().exec()方法可以传入一个字符串数组,其中第一个元素是命令路径,后续是参数,执行adb devices命令的代码片段如下:
try {
Process process = Runtime.getRuntime().exec(new String[]{"adb", "devices"});
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
上述代码中,Process对象表示adb命令的执行进程,BufferedReader用于读取命令的输出结果。waitFor()方法会阻塞当前线程,直到进程执行完成,需要注意的是,exec()方法在Windows和Linux/macOS上的命令路径可能不同,因此需要确保adb命令已添加到系统环境变量中,或使用绝对路径。
相比之下,ProcessBuilder类提供了更灵活的进程管理方式,它允许设置工作目录、环境变量,并支持重定向输入输出流,执行adb shell pm list packages命令的代码如下:
try {
ProcessBuilder pb = new ProcessBuilder("adb", "shell", "pm", "list", "packages");
pb.redirectErrorStream(true); // 合并错误流和输出流
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
ProcessBuilder的优势在于可以更精细地控制进程的执行环境,例如通过environment()方法设置环境变量,或通过directory()方法指定工作目录。

在执行adb命令时,可能会遇到一些常见问题,命令执行超时或输出流阻塞,为了避免进程阻塞,可以单独启动一个线程来读取输出流,或者使用Process.destroy()方法强制终止进程,对于需要长时间运行的命令(如adb logcat),建议使用异步方式处理输出流。
以下是执行adb命令时需要注意的几点:
- 环境配置:确保adb命令在系统路径中可用,或提供完整路径。
- 权限问题:Java程序需要足够的权限执行adb命令,尤其是在Linux/macOS系统上可能需要root权限。
- 输出处理:及时读取命令的输出流和错误流,避免缓冲区满导致进程阻塞。
- 异常处理:捕获
IOException和InterruptedException,确保程序健壮性。
以下是一个通过Java执行adb命令并获取设备列表的完整示例,使用表格展示不同设备的序列号和状态:
| 设备序列号 | 状态 |
|---|---|
| emulator-5554 | device |
| 168.1.100:5555 | device |
在实现过程中,可以通过解析adb命令的输出来提取设备信息,并将其存储到数据结构中供后续使用,使用正则表达式匹配设备序列号和状态:

Pattern pattern = Pattern.compile("^([a-zA-Z0-9-]+)\\s+device$");
while ((line = reader.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
String deviceId = matcher.group(1);
System.out.println("Device ID: " + deviceId);
}
}
相关问答FAQs:
Q1: 如何在Java中执行adb命令并获取命令的退出码?
A1: 可以通过Process.waitFor()方法获取进程的退出码。int exitCode = process.waitFor();,其中exitCode为0表示命令执行成功,非零表示失败。Process.exitValue()方法也可以获取退出码,但需注意该方法在进程未结束时调用会抛出IllegalThreadStateException。
Q2: 为什么执行adb命令时会出现“adb命令不是内部或外部命令”的错误?
A2: 该错误通常是因为adb命令未添加到系统环境变量中,解决方法有两种:一是将adb工具的路径添加到系统的PATH环境变量中;二是在Java代码中直接使用adb的完整路径,例如new String[]{"C:\\path\\to\\adb.exe", "devices"},确保路径正确且程序有访问权限即可。
