• [Java][Android][Process] ProcessBuilder与Runtime差别


    在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个已经创建的进程,而外部的线程反复利用以及创建的进程,不知这样是否可行?

    望大家探讨一下解决方法。谢谢了。

  • 相关阅读:
    Java内存模型与共享变量可见性
    CopyOnWriteArraySet源码解析
    CopyOnWriteArrayList源码解析(1)
    CopyOnWriteArrayList源码解析(2)
    CopyOnWriteArrayList源码解析
    企业项目开发--切分配置文件
    常用Java集合类总结
    HashSet源码解析
    Flutter中的普通路由与命名路由(Navigator组件)
    Flutter——BottomNavigationBar组件(底部导航栏组件)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5123960.html
Copyright © 2020-2023  润新知