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

原文地址:https://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下执行就不会有效果:

		Process process = null;
		InputStream instream = null;
		BufferedReader bufferReader = null;
 
		try {
			process = Runtime.getRuntime().exec(command);
 
			instream = process.getInputStream();
			bufferReader = new BufferedReader(new InputStreamReader(instream, "GBK"));
 
			String readline;
			while ((readline = bufferReader.readLine()) != null) {
					results.add(readline);
//					Log.i(TAG, "execute command result : " + readline);
			}
 
			int status = process.waitFor();
			Log.i(TAG, "execute command :" + command + ", status : " + status);
 
		} catch (IOException e) {
			Log.e(TAG, e.getMessage());
		} catch (InterruptedException e) {
			Log.e(TAG, e.getMessage());
		}

这种常规的操作,如果执行一条Ping命令,当在某个ip下卡住ping不通时,就有问题了,会发现代码一直会阻塞在br.readLine()的地方,任何办法都不好解决,网上说的把操作放在另外一个Thread里进行,只是解决了process.waiFor()的阻塞问题。其实也解决不了当进行ping不通时readline阻塞的问题,在ping命令的操作下使用readline并不像读取一个文件,当遇到换行时会结束,ping不通,只能一直阻塞着,除非在外部进行close等操作。

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

package com.vixtel.netvista.gdcmcc.utils;
 
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.util.Log;
 
/***
 * 执行命令行工具类
 * 
 * @author yangxiaolong 2014-04-30
 * 
 */
public class CommandUtil {
 
	public static final String TAG = CommandUtil.class.getSimpleName();
	public static final String COMMAND_SH = "sh";
	public static final String COMMAND_LINE_END = "\n";
	public static final String COMMAND_EXIT = "exit\n";
	private static final boolean ISDEBUG = true;
 
	/**
	 * 执行单条命令
	 * 
	 * @param command
	 * @return
	 */
	public static List<String> execute(String command) {
		return execute(new String[] { command });
	}
 
	/**
	 * 可执行多行命令(bat)
	 * 
	 * @param commands
	 * @return
	 */
	public static List<String> execute(String[] commands) {
		List<String> results = new ArrayList<String>();
		int status = -1;
		if (commands == null || commands.length == 0) {
			return null;
		}
		debug("execute command start : " + commands);
		Process process = null;
		BufferedReader successReader = null;
		BufferedReader errorReader = null;
		StringBuilder errorMsg = null;
 
		DataOutputStream dos = null;
		try {
			// TODO
			process = Runtime.getRuntime().exec(COMMAND_SH);
			dos = new DataOutputStream(process.getOutputStream());
			for (String command : commands) {
				if (command == null) {
					continue;
				}
				dos.write(command.getBytes());
				dos.writeBytes(COMMAND_LINE_END);
				dos.flush();
			}
			dos.writeBytes(COMMAND_EXIT);
			dos.flush();
 
			status = process.waitFor();
 
			errorMsg = new StringBuilder();
			successReader = new BufferedReader(new InputStreamReader(
					process.getInputStream()));
			errorReader = new BufferedReader(new InputStreamReader(
					process.getErrorStream()));
			String lineStr;
			while ((lineStr = successReader.readLine()) != null) {
				results.add(lineStr);
				debug(" command line item : " + lineStr);
			}
			while ((lineStr = errorReader.readLine()) != null) {
				errorMsg.append(lineStr);
			}
 
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (dos != null) {
					dos.close();
				}
				if (successReader != null) {
					successReader.close();
				}
				if (errorReader != null) {
					errorReader.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
 
			if (process != null) {
				process.destroy();
			}
		}
		debug(String.format(Locale.CHINA,
				"execute command end,errorMsg:%s,and status %d: ", errorMsg,
				status));
		return results;
	}
 
	/**
	 * DEBUG LOG
	 * 
	 * @param message
	 */
	private static void debug(String message) {
		if (ISDEBUG) {
			Log.d(TAG, message);
		}
	}
 
}
 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值