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

原文地址: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():

[java]  view plain copy
  1. Process process = new ProcessBuilder("/system/bin/ping").redirectErrorStream(true).start();  
  2. OutputStream stdout = process.getOutputStream();  
  3. InputStream stdin = process.getInputStream();  
  4. BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));  
  5. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdout));  


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

[java]  view plain copy
  1. Process process = Runtime.getRuntime().exec("/system/bin/ping");  
  2. OutputStream stdout = process.getOutputStream();  
  3. InputStream stderr = process.getErrorStream();  
  4. InputStream stdin = process.getInputStream();  
  5. BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));  
  6. BufferedReader err= new BufferedReader(new InputStreamReader(stderr));  
  7. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdout));  

两者在执行效率上没啥区别,可能是我没有发现。两种测试的区别在于是否可以重定向错误流。

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

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


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

[java]  view plain copy
  1. import java.io.InputStream;  
  2. import java.io.OutputStream;  
  3.   
  4. public class ProcessModel {  
  5.   
  6.     /** 
  7.      * 通过Android底层实现进程关闭 
  8.      * 
  9.      * @param process 
  10.      */  
  11.     public static void killProcess(Process process) {  
  12.         int pid = getProcessId(process.toString());  
  13.         if (pid != 0) {  
  14.             try {  
  15.                 android.os.Process.killProcess(pid);  
  16.             } catch (Exception e) {  
  17.                 try {  
  18.                     process.destroy();  
  19.                 } catch (Exception ex) {  
  20.                 }  
  21.             }  
  22.         }  
  23.     }  
  24.   
  25.     /** 
  26.      * 获取当前进程的ID 
  27.      * 
  28.      * @param str 
  29.      * @return 
  30.      */  
  31.     public static int getProcessId(String str) {  
  32.         try {  
  33.             int i = str.indexOf("=") + 1;  
  34.             int j = str.indexOf("]");  
  35.             String cStr = str.substring(i, j).trim();  
  36.             return Integer.parseInt(cStr);  
  37.         } catch (Exception e) {  
  38.             return 0;  
  39.         }  
  40.     }  
  41.   
  42.   
  43.     /** 
  44.      * 关闭进程的所有流 
  45.      * 
  46.      * @param process 
  47.      */  
  48.     public static void closeAllStream(Process process) {  
  49.         try {  
  50.             InputStream in = process.getInputStream();  
  51.             if (in != null)  
  52.                 in.close();  
  53.         } catch (Exception e) {  
  54.             e.printStackTrace();  
  55.         }  
  56.         try {  
  57.             InputStream in = process.getErrorStream();  
  58.             if (in != null)  
  59.                 in.close();  
  60.         } catch (Exception e) {  
  61.             e.printStackTrace();  
  62.         }  
  63.         try {  
  64.             OutputStream out = process.getOutputStream();  
  65.             if (out != null)  
  66.                 out.close();  
  67.         } catch (Exception e) {  
  68.             e.printStackTrace();  
  69.         }  
  70.     }  
  71.   
  72.     /** 
  73.      * 销毁一个进程 
  74.      * 
  75.      * @param process 
  76.      */  
  77.     public static void processDestroy(Process process) {  
  78.         if (process != null) {  
  79.             try {  
  80.                 if (process.exitValue() != 0) {  
  81.                     closeAllStream(process);  
  82.                     killProcess(process);  
  83.                 }  
  84.             } catch (IllegalThreadStateException e) {  
  85.                 closeAllStream(process);  
  86.                 killProcess(process);  
  87.             }  
  88.         }  
  89.     }  
  90.   
  91.   
  92.     /** 
  93.      * 通过线程进行异步销毁 
  94.      * 
  95.      * @param process 
  96.      */  
  97.     public static void asyncProcessDestroy(final Process process) {  
  98.         Thread thread = new Thread(new Runnable() {  
  99.             @Override  
  100.             public void run() {  
  101.                 processDestroy(process);  
  102.             }  
  103.         });  
  104.         thread.setDaemon(true);  
  105.         thread.start();  
  106.     }  
  107. }  



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

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

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值