[Android] [Java] 分享 Process 執行命令列封裝類,androidprocess
在上一篇文章中提到,利用Java建立進程執行命令列語句建立過多後會出現無法建立進程的問題。
[Android] ProcessBuilder與Runtime.getRuntime().exec分別建立進程的區別
進行多次測試後發現是因為沒有正常退出進程,以及完全讀取掉流資料,和關閉流導致的問題。
在多次最佳化後,建立如下封裝類:
ProcessModel.java
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;/** * Create By Qiujuer * 2014-07-26 * <p/> * 執行命令列語句靜態方法封裝 */public class ProcessModel { //分行符號 private static final String BREAK_LINE; //執行退出命令 private static final byte[] COMMAND_EXIT; //錯誤緩衝 private static byte[] BUFFER; /** * 靜態變數初始化 */ static { BREAK_LINE = "\n"; COMMAND_EXIT = "\nexit\n".getBytes(); BUFFER = new byte[32]; } /** * 執行命令 * * @param params 命令參數 * <pre> eg: "/system/bin/ping", "-c", "4", "-s", "100","www.qiujuer.net"</pre> * @return 執行結果 */ public static String execute(String... params) { Process process = null; StringBuilder sbReader = null; BufferedReader bReader = null; InputStreamReader isReader = null; InputStream in = null; InputStream err = null; OutputStream out = null; try { process = new ProcessBuilder() .command(params) .start(); out = process.getOutputStream(); in = process.getInputStream(); err = process.getErrorStream(); out.write(COMMAND_EXIT); out.flush(); process.waitFor(); isReader = new InputStreamReader(in); bReader = new BufferedReader(isReader); String s; if ((s = bReader.readLine()) != null) { sbReader = new StringBuilder(); sbReader.append(s); sbReader.append(BREAK_LINE); while ((s = bReader.readLine()) != null) { sbReader.append(s); sbReader.append(BREAK_LINE); } } while ((err.read(BUFFER)) > 0) { } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { closeAllStream(out, err, in, isReader, bReader); if (process != null) { processDestroy(process); process = null; } } if (sbReader == null) return null; else return sbReader.toString(); } /** * 關閉所有流 * * @param out 輸出資料流 * @param err 錯誤流 * @param in 輸入資料流 * @param isReader 輸入資料流封裝 * @param bReader 輸入資料流封裝 */ private static void closeAllStream(OutputStream out, InputStream err, InputStream in, InputStreamReader isReader, BufferedReader bReader) { if (out != null) try { out.close(); } catch (IOException e) { e.printStackTrace(); } if (err != null) try { err.close(); } catch (IOException e) { e.printStackTrace(); } if (in != null) try { in.close(); } catch (IOException e) { e.printStackTrace(); } if (isReader != null) try { isReader.close(); } catch (IOException e) { e.printStackTrace(); } if (bReader != null) try { bReader.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 通過Android底層實現進程關閉 * * @param process 進程 */ private static void killProcess(Process process) { int pid = getProcessId(process); if (pid != 0) { try { //android kill process android.os.Process.killProcess(pid); } catch (Exception e) { try { process.destroy(); } catch (Exception ex) { } } } } /** * 擷取進程的ID * * @param process 進程 * @return */ private static int getProcessId(Process process) { String str = process.toString(); try { int i = str.indexOf("=") + 1; int j = str.indexOf("]"); str = str.substring(i, j); return Integer.parseInt(str); } catch (Exception e) { return 0; } } /** * 銷毀進程 * * @param process 進程 */ private static void processDestroy(Process process) { if (process != null) { try { //判斷是否正常退出 if (process.exitValue() != 0) { killProcess(process); } } catch (IllegalThreadStateException e) { killProcess(process); } } }}
在進行批量壓力測試到達125643個線程的時候都沒有出現此問題;特此分享給大家。
怎用java執行命令列
運行cmd.exe 這個程式捕捉process.get InputStream 讀取輸出,捕捉.getOutputStream 發送命令。
命令列執行 java 提示找不到主類
cmd命令中不是java hello.class應該是java hello
你試試