Android通过Runtime.getRuntime().exec实现Ping和Traceroute命令时readLine阻塞问题解决

来源:互联网 发布:2016淘宝排名突然下降 编辑:程序博客网 时间:2024/06/05 07:33

http://blog.csdn.net/mad1989/article/details/25071957


在PC上调用cmd,进行一些常用的命令操作,在Android上的是通过Runtime.getRuntime().exec来执行底层Linux下的程序或脚本(bat)。


首先连接上真机,电脑打开CMD,输入adb-shell,确保你要进行的脚本语言是可以执行的。(比如常见的ping命令)


但是深入一下,发现使用ping命令,并附加一些参数,我们设置 -w 5 了,希望5秒钟如果没有ping通,可以有返回,可是像如下常规的操作,貌似ping下的附加参数是不会起作用的,也就是说在cmd下,我希望ping后5秒没有收到包就返回,但是在android下执行就不会有效果:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.         Process process = null;  
  2.         InputStream instream = null;  
  3.         BufferedReader bufferReader = null;  
  4.   
  5.         try {  
  6.             process = Runtime.getRuntime().exec(command);  
  7.   
  8.             instream = process.getInputStream();  
  9.             bufferReader = new BufferedReader(new InputStreamReader(instream, "GBK"));  
  10.   
  11.             String readline;  
  12.             while ((readline = bufferReader.readLine()) != null) {  
  13.                     results.add(readline);  
  14. //                  Log.i(TAG, "execute command result : " + readline);  
  15.             }  
  16.   
  17.             int status = process.waitFor();  
  18.             Log.i(TAG, "execute command :" + command + ", status : " + status);  
  19.   
  20.         } catch (IOException e) {  
  21.             Log.e(TAG, e.getMessage());  
  22.         } catch (InterruptedException e) {  
  23.             Log.e(TAG, e.getMessage());  
  24.         }  
这种常规的操作,如果执行一条Ping命令,当在某个ip下卡住ping不通时,就有问题了,会发现代码一直会阻塞在br.readLine()的地方,任何办法都不好解决,网上说的把操作放在另外一个Thread里进行,只是解决了process.waiFor()的阻塞问题。其实也解决不了当进行ping不通时readline阻塞的问题,在ping命令的操作下使用readline并不像读取一个文件,当遇到换行时会结束,ping不通,只能一直阻塞着,除非在外部进行close等操作。

结合国内外论坛,终于找到一个办法,我写成了一个方法类,供大家参考(可直接调用):

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.vixtel.netvista.gdcmcc.utils;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.DataOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9. import java.util.Locale;  
  10. import android.util.Log;  
  11.   
  12. /*** 
  13.  * 执行命令行工具类 
  14.  *  
  15.  * @author yangxiaolong 2014-04-30 
  16.  *  
  17.  */  
  18. public class CommandUtil {  
  19.   
  20.     public static final String TAG = CommandUtil.class.getSimpleName();  
  21.     public static final String COMMAND_SH = "sh";  
  22.     public static final String COMMAND_LINE_END = "\n";  
  23.     public static final String COMMAND_EXIT = "exit\n";  
  24.     private static final boolean ISDEBUG = true;  
  25.   
  26.     /** 
  27.      * 执行单条命令 
  28.      *  
  29.      * @param command 
  30.      * @return 
  31.      */  
  32.     public static List<String> execute(String command) {  
  33.         return execute(new String[] { command });  
  34.     }  
  35.   
  36.     /** 
  37.      * 可执行多行命令(bat) 
  38.      *  
  39.      * @param commands 
  40.      * @return 
  41.      */  
  42.     public static List<String> execute(String[] commands) {  
  43.         List<String> results = new ArrayList<String>();  
  44.         int status = -1;  
  45.         if (commands == null || commands.length == 0) {  
  46.             return null;  
  47.         }  
  48.         debug("execute command start : " + commands);  
  49.         Process process = null;  
  50.         BufferedReader successReader = null;  
  51.         BufferedReader errorReader = null;  
  52.         StringBuilder errorMsg = null;  
  53.   
  54.         DataOutputStream dos = null;  
  55.         try {  
  56.             // TODO  
  57.             process = Runtime.getRuntime().exec(COMMAND_SH);  
  58.             dos = new DataOutputStream(process.getOutputStream());  
  59.             for (String command : commands) {  
  60.                 if (command == null) {  
  61.                     continue;  
  62.                 }  
  63.                 dos.write(command.getBytes());  
  64.                 dos.writeBytes(COMMAND_LINE_END);  
  65.                 dos.flush();  
  66.             }  
  67.             dos.writeBytes(COMMAND_EXIT);  
  68.             dos.flush();  
  69.   
  70.             status = process.waitFor();  
  71.   
  72.             errorMsg = new StringBuilder();  
  73.             successReader = new BufferedReader(new InputStreamReader(  
  74.                     process.getInputStream()));  
  75.             errorReader = new BufferedReader(new InputStreamReader(  
  76.                     process.getErrorStream()));  
  77.             String lineStr;  
  78.             while ((lineStr = successReader.readLine()) != null) {  
  79.                 results.add(lineStr);  
  80.                 debug(" command line item : " + lineStr);  
  81.             }  
  82.             while ((lineStr = errorReader.readLine()) != null) {  
  83.                 errorMsg.append(lineStr);  
  84.             }  
  85.   
  86.         } catch (IOException e) {  
  87.             e.printStackTrace();  
  88.         } catch (Exception e) {  
  89.             e.printStackTrace();  
  90.         } finally {  
  91.             try {  
  92.                 if (dos != null) {  
  93.                     dos.close();  
  94.                 }  
  95.                 if (successReader != null) {  
  96.                     successReader.close();  
  97.                 }  
  98.                 if (errorReader != null) {  
  99.                     errorReader.close();  
  100.                 }  
  101.             } catch (IOException e) {  
  102.                 e.printStackTrace();  
  103.             }  
  104.   
  105.             if (process != null) {  
  106.                 process.destroy();  
  107.             }  
  108.         }  
  109.         debug(String.format(Locale.CHINA,  
  110.                 "execute command end,errorMsg:%s,and status %d: ", errorMsg,  
  111.                 status));  
  112.         return results;  
  113.     }  
  114.   
  115.     /** 
  116.      * DEBUG LOG 
  117.      *  
  118.      * @param message 
  119.      */  
  120.     private static void debug(String message) {  
  121.         if (ISDEBUG) {  
  122.             Log.d(TAG, message);  
  123.         }  
  124.     }  
  125.   
  126. }  
0 0
原创粉丝点击