[Java][Android][Process] ProcessBuilder与Runtime区别

Posted Qiujuer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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][Android][Process] ProcessBuilder与Runtime区别的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio出现java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessExcep

错误记录Android 中调用 Process 命令行执行指令 ( java.lang.IllegalThreadStateException: process hasn‘t exited )(代码片

[Java][Android][Process] ProcessBuilder与Runtime区别

Android app_process的使用

Android异常:唤醒锁未授权。(Caused by: java.lang.SecurityException: Neither user 10044 nor current process has

Android 开创java世界(JNI Invocation API)