Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android ProcessBuilder與Runtime.getRuntime().exec分別創建進程的區別

Android ProcessBuilder與Runtime.getRuntime().exec分別創建進程的區別

編輯:關於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));


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

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個已經創建的進程,而外部的線程重復利用以及創建的進程,不知這樣是否可行?

望大家探討一下解決方法,謝謝了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved