Android执行shell命令无返回结果的技术求助
解决Android中执行Shell命令无输出的问题
我完全懂你折腾了好几个小时却连个输出都看不到的崩溃感,咱们来一步步排查你代码里的问题,解决这个shell命令输出的问题。
你的代码里存在几个关键问题,导致无法正确获取命令输出:
- 没有等待进程执行完毕就开始读取流,可能进程还没来得及输出内容
- 直接将整个
ByteArray转为String,会包含上一次读取的残留垃圾数据 - 没有处理错误输出流,万一命令执行有错误信息,你完全看不到
- 未指定字符编码,可能导致读取时出现隐形异常或乱码
修正后的完整代码
fun executeShellCommand(command: String): String { val outputBuilder = StringBuilder() val errorBuilder = StringBuilder() try { // 将命令拆分为列表(处理带参数的命令更安全,比如"/system/bin/ls -l") val commandParts = command.split(" ").filter { it.isNotEmpty() } val process = ProcessBuilder(commandParts) .redirectErrorStream(true) // 把错误输出合并到标准输入流,方便统一读取 .start() // 等待进程完全执行结束,确保输出已全部写入流 process.waitFor() // 使用BufferedReader高效读取,指定UTF-8编码避免乱码,use函数自动关闭流 process.inputStream.bufferedReader(Charsets.UTF_8).use { reader -> var line: String? while (reader.readLine().also { line = it } != null) { outputBuilder.append(line).append("\n") } } } catch (ex: IOException) { ex.printStackTrace() errorBuilder.append("执行异常: ${ex.message}") } // 优先返回标准输出,无输出则返回错误信息 return if (outputBuilder.isNotEmpty()) { outputBuilder.toString().trim() } else { errorBuilder.toString() } } // 调用示例 val result = executeShellCommand("/system/bin/ls") println("Output: $result")
关键优化点说明
- 拆分命令为列表:如果后续需要执行带参数的命令(比如
ls -l /sdcard),这种方式能避免参数解析错误 - 合并错误流:
redirectErrorStream(true)可以把命令的错误输出和标准输出合并到同一个流,不用单独处理两个流 - 等待进程结束:
process.waitFor()会阻塞当前线程,直到命令执行完成,确保所有输出都已写入流中 - 使用BufferedReader:相比直接操作
ByteArray,它能自动处理换行和残留数据问题,同时指定编码保证字符正确 - 自动关闭流:
use函数会在代码块执行完毕后自动关闭流,避免资源泄漏
额外注意事项
如果后续执行其他命令仍然无输出,需要考虑Android的权限限制:
- 对于Android 11及以上版本,访问某些系统目录或文件需要特殊权限(比如
MANAGE_EXTERNAL_STORAGE) - 部分命令需要root权限才能执行,如果你的设备未root,这类命令会执行失败
内容的提问来源于stack exchange,提问作者m33ts4k0z
相关产品推荐
相关产品推荐

