Runtime.getRuntime().exec() 解析

函数解析

该方法是用来实现shell 命令的,但是与传统的adb shell不同,该方法有6个重载函数:

public Process exec(String command)-----在单独的进程中执行指定的字符串命令。
public Process exec(String [] cmdArray)---在单独的进程中执行指定命令和变量
public Process exec(String command, String [] envp)----在指定环境的独立进程中执行指定命令和变量
public Process exec(String [] cmdArray, String [] envp)----在指定环境的独立进程中执行指定的命令和变量
public Process exec(String command,String[] envp,File dir)----在有指定环境和工作目录的独立进程中执行指定的字符串命令
public Process exec(String[] cmdarray,String[] envp,File dir)----在指定环境和工作目录的独立进程中执行指定的命令和变

其中最常使用的就是Process exec(String command)方法。

例如:

Runtime.getRuntime().exec("ls");

但是实际上以上6种方法最终都是调用的

public Process exec(String command, String[] envp, File dir)

方法。

因此该api分为在liunx环境下调用和在windows环境下调用。

在windows环境下:

最终调用的是cmd文件

Runtime.getRuntime().exec(new String[]{ "cmd", "/c", cmds});

在Linux环境下:

则是调用的/bin/sh文件,然后-c执行起命令

Runtime.getRuntime().exec(new String[]{"/bin/sh","-c", cmds});

我们可以去看bin目录下的sh文件,-help能查看其用法

OPTIONS:
-c string    该选项表明string中包含了一条命令.如 bash -c ls ~
-i       使Bash以交互式方式运行
-r       使Bash以受限方式运行
–login     使Bash以登录Shell方式运行
–posix     使Bash遵循POSIX标准
–verbose    使Bash显示所有其读入的输入行
–help     打印Bash的使用信息
–version    打印版本信息

因此我们可以得知,若我们在Android手机上使用Runtime.getRuntime().exec(”ls")命令

最终调用的是Runtime.getRuntime().exec(new String[]{"/bin/sh","-c", "ls"});命令

Process对象

通过Runtime.getRuntime().exec()函数执行后,会返回一个Process对象,该对象有以下几种用法:

1.destroy();杀掉子进程
2.exitValue();返回子进程的出口值,值0表示正常终止
3.getErrorStream();获取自己进程错误输出的输入流
4.getInputStream();这里是获取子进程输出的输入流
5.getOutputStream();获取子进程输入的输出流
6.waitFor();导致当前线程等待,如有必要,一直要等到由该Process对象表示的进程已经终止,如果已终止该子进程,此方法立即返回,如果没有终止该子进程,调用的线程将被阻塞,直到推出子进程,根据惯例,0表示正常终止

通过该对象,利用getInputStream(),就能拿到shell返回的String字符串

cd命令

由于Runtime.getRuntime().exec()命令会在当前环境开启一个进程进行执行,而cd命令会跳转到不同的环境,因此若一条一条的执行cd命令则无法执行,需要使用“;”or"&&",一次性执行所有命令,才能执行cd命令。

例如:

Runtime.getRuntime().exec(new String[]{"/bin/sh","-c", "cd /system;ls -l"});

此外:

若是需要先执行su命令再执行cd命令,由于su命令后,使用“;”,无法衔接后续命ut令

因此必须先使用su命令,获取Process对象后,利用getOutputStream(),write后续命令。

例如:

exec("cd /system/app; mount -o remount,rw /;mkdir tobesystem3 ;ls -l");

代码示例:

    private static String exec(String command) {
        BufferedOutputStream bufferedOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            bufferedOutputStream = new BufferedOutputStream(process.getOutputStream());

            bufferedInputStream = new BufferedInputStream(process.getInputStream());
            bufferedOutputStream.write(command.getBytes());
            bufferedOutputStream.write('\n');
            bufferedOutputStream.flush();
            bufferedOutputStream.close();

            process.waitFor();

            String outputStr = getStrFromBufferInputSteam(bufferedInputStream);
            return outputStr;
        } catch (Exception e) {
            return null;
        } finally {
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (process != null) {
                process.destroy();
            }
        }
    }

    private static String getStrFromBufferInputSteam(BufferedInputStream bufferedInputStream) {
        if (null == bufferedInputStream) {
            return "";
        }
        int BUFFER_SIZE = 512;
        byte[] buffer = new byte[BUFFER_SIZE];
        StringBuilder result = new StringBuilder();
        try {
            while (true) {
                int read = bufferedInputStream.read(buffer);
                if (read > 0) {
                    result.append(new String(buffer, 0, read));
                }
                if (read < BUFFER_SIZE) {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值