編輯:關於Android編程
在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));
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個已經創建的進程,而外部的線程重復利用以及創建的進程,不知這樣是否可行?
望大家探討一下解決方法,謝謝了。
每天看郭神的公眾號文章已經成了我的一個習慣,前段時間看到一篇文章,ActivityThread的main()方法究竟做了什麼工作?main方法代碼並不長,但行行珠玑。我也
最近在學習FM模塊,FM是一個值得學習的模塊,可以從上層看到底層。上層就是FM的按扭操作和界面顯示,從而調用到FM底層驅動來實現廣播收聽的功能。 看看
之所以把PopupWindow與懸浮窗這兩個放到一起講,是因為這兩個的實現原理基本是一致的,只是有點不同而已。 原理: 使用系統服務(WindowManag
安卓右鍵工具,集成dex轉jar,二進制xml查看,apk相關信息查詢,apk圖標提取,apk優化,手機屏幕截圖,安裝卸載,簽名,反編譯和回編譯等功能,方便快捷,開發者們