[Java][Android][Process] ProcessBuilder与Runtime差别

时间:2023-03-09 08:24:36
[Java][Android][Process] ProcessBuilder与Runtime差别

在Android中想要进行Ping,在不Root机器的情况下似乎还仅仅能进行底层命调用才干实现。

由于在Java中要进行ICMP包发送须要Root权限。

于是仅仅能通过创建进程来攻克了。创建进程在Java中有两种方式,分别为:

1. 调用ProcessBuilder的构造函数后运行start()

2. 用Runtime.getRuntime().exec()方法运行





经过使用后发现两者有差别可是也并非非常大,两个样例说明:





1.调用ProcessBuilder的构造函数后运行start():

Process process = new ProcessBuilder("/system/bin/ping").redirectErrorStream(true).start();
OutputStream stdout = process.getOutputStream();
InputStream stdin = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdout));

2.用Runtime.getRuntime().exec()方法运行:

Process process = Runtime.getRuntime().exec("/system/bin/ping");
OutputStream stdout = process.getOutputStream();
InputStream stderr = process.getErrorStream();
InputStream stdin = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));
BufferedReader err= new BufferedReader(new InputStreamReader(stderr));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdout));

两者在运行效率上没啥差别,可能是我没有发现。

两种測试的差别在于能否够重定向错误流。

使用ProcessBuilder,能够通过redirectErrorStream(true)将错误输出流转移到标准输出流中,这样使用一次process.getInputStreamReader()就能读出该进程的全部输出。

而使用Runtime.getRuntime().exec()方法时。错误的输出流还需通过process.getErrorStream()来获得。

分享一个自己集合的一个进程运行后销毁的类:

import java.io.InputStream;
import java.io.OutputStream; public class ProcessModel { /**
* 通过Android底层实现进程关闭
*
* @param process
*/
public static void killProcess(Process process) {
int pid = getProcessId(process.toString());
if (pid != 0) {
try {
android.os.Process.killProcess(pid);
} catch (Exception e) {
try {
process.destroy();
} catch (Exception ex) {
}
}
}
} /**
* 获取当前进程的ID
*
* @param str
* @return
*/
public static int getProcessId(String str) {
try {
int i = str.indexOf("=") + 1;
int j = str.indexOf("]");
String cStr = str.substring(i, j).trim();
return Integer.parseInt(cStr);
} catch (Exception e) {
return 0;
}
} /**
* 关闭进程的全部流
*
* @param process
*/
public static void closeAllStream(Process process) {
try {
InputStream in = process.getInputStream();
if (in != null)
in.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
InputStream in = process.getErrorStream();
if (in != null)
in.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
OutputStream out = process.getOutputStream();
if (out != null)
out.close();
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 销毁一个进程
*
* @param process
*/
public static void processDestroy(Process process) {
if (process != null) {
try {
if (process.exitValue() != 0) {
closeAllStream(process);
killProcess(process);
}
} catch (IllegalThreadStateException e) {
closeAllStream(process);
killProcess(process);
}
}
} /**
* 通过线程进行异步销毁
*
* @param process
*/
public static void asyncProcessDestroy(final Process process) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
processDestroy(process);
}
});
thread.setDaemon(true);
thread.start();
}
}

奇怪的是,当使用线程进行大量的进程创建。最后达到一定数量(大约为1000个左右)的时候将会出现无法创建进程的情况;

此情况我不知怎么解决,自己想的是弄一个线程池里边放20个已经创建的进程,而外部的线程反复利用以及创建的进程,不知这样是否可行?

望大家探讨一下解决方法。谢谢了。