Android执行程序或脚本的方法

Java中提供了两种方法来执行程序或脚本:
(1) 使用Runtime的exec()方法
(2) 使用ProcessBuilder的start()方法

ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来控制进程状态并获得相关信息。 

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

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()方法执行:

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()来获得。

waitFor方法

ProcessBuilder.start() 和 Runtime.exec() 方法创建Process 子类的一个实例。 程序主进程会等待process一定的时间,但是时间很少,可能process根本无法完成工作就结束了。 因此,针对使用较长时间做工作的process,就需要调用waitFor方法。 该方法会引起当前Thread等待,直到process中断。 

此方法返回的退出值的过程。按照惯例,0表示正常终止。

下面是一个进程执行后销毁的类:

  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 }  

为了防止主控程序被waitfor方法阻塞,需要自己新建线程来处理Process流

 1 Process p = Runtime.getRuntime().exec(cmd);  
 2   
 3 StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");              
 4         
 5       // kick off stderr  
 6       errorGobbler.start();  
 7         
 8       StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), "STDOUT");  
 9       // kick off stdout  
10       outGobbler.start();   
11   
12 p.waitFor();  
 1   
 2 import java.io.BufferedReader;  
 3 import java.io.IOException;  
 4 import java.io.InputStream;  
 5 import java.io.InputStreamReader;  
 6 import java.io.OutputStream;  
 7 import java.io.PrintWriter;  
 8   
 9 import com.sdc.callmaxent.util.FileUtil;  
10   
11 /** 
12  * 用于处理Runtime.getRuntime().exec产生的错误流及输出流 
13  * @author shaojing 
14  * 
15  */  
16 public class StreamGobbler extends Thread {  
17     InputStream is;  
18     String type;  
19     OutputStream os;  
20           
21     StreamGobbler(InputStream is, String type) {  
22         this(is, type, null);  
23     }  
24   
25     StreamGobbler(InputStream is, String type, OutputStream redirect) {  
26         this.is = is;  
27         this.type = type;  
28         this.os = redirect;  
29     }  
30       
31     public void run() {  
32         InputStreamReader isr = null;  
33         BufferedReader br = null;  
34         PrintWriter pw = null;  
35         try {  
36             if (os != null)  
37                 pw = new PrintWriter(os);  
38                   
39             isr = new InputStreamReader(is);  
40             br = new BufferedReader(isr);  
41             String line=null;  
42             while ( (line = br.readLine()) != null) {  
43                 if (pw != null)  
44                     pw.println(line);  
45                 System.out.println(type + ">" + line);      
46             }  
47               
48             if (pw != null)  
49                 pw.flush();  
50         } catch (IOException ioe) {  
51             ioe.printStackTrace();    
52         } finally{  
53             FileUtil.close(pw);  
54             FileUtil.close(br);  
55             FileUtil.close(isr);  
56         }  
57     }  
58 }   

ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来控制进程状态并获得相关信息。 

 

 

原文地址:https://www.cnblogs.com/l2rf/p/5866119.html