原文地址:http://blog.csdn.net/qiujuer/article/details/38086071
在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个已经创建的进程,而外部的线程重复利用以及创建的进程,不知这样是否可行?
望大家探讨一下解决方法,谢谢了。