在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);
}
}
}