在Android中想要進行Ping,在不Root機器的情況下似乎還隻能進行底層命調用才能實作。
因為在Java中要進行ICMP包發送需要Root權限。
于是隻能通過建立程序來解決了,建立程序在Java中有兩種方式,分别為:
1. 調用ProcessBuilder的構造函數後執行start()
2. 用Runtime.getRuntime().exec()方法執行
經過使用後發現兩者有差別但是也并不是很大,兩個例子說明:
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()來獲得。
分享一個自己集合的一個程序執行後銷毀的類:
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. new Thread(new Runnable() {
99. @Override
100. public void run() {
101. processDestroy(process);
102. }
103. });
104. true);
105. thread.start();
106. }
107. }
奇怪的是,當使用線程進行大量的程序建立,最後達到一定數量(大約為1000個左右)的時候将會出現無法建立程序的情況;
此情況我不知怎麼解決,自己想的是弄一個線程池裡邊放20個已經建立的程序,而外部的線程重複利用以及建立的程序,不知這樣是否可行?