Android 命令行执行工具类
最近在做android项目的时候,需要执行命令行命令,之前在网上找的不仅杂乱而且错误多,于是自己写了一份。
话不多说,直接上代码
import android.util.Log; import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import static java.lang.Runtime.getRuntime; /**
* 执行命令的类
* Created by Kappa
*/
public class ExeCommand {
//shell进程
private Process process;
//对应进程的3个流
private BufferedReader successResult;
private BufferedReader errorResult;
private DataOutputStream os;
//是否同步,true:run会一直阻塞至完成或超时。false:run会立刻返回
private boolean bSynchronous;
//表示shell进程是否还在运行
private boolean bRunning = false;
//同步锁
ReadWriteLock lock = new ReentrantReadWriteLock(); //保存执行结果
private StringBuffer result = new StringBuffer(); /**
* 构造函数
*
* @param synchronous true:同步,false:异步
*/
public ExeCommand(boolean synchronous) {
bSynchronous = synchronous;
} /**
* 默认构造函数,默认是同步执行
*/
public ExeCommand() {
bSynchronous = true;
} /**
* 还没开始执行,和已经执行完成 这两种情况都返回false
*
* @return 是否正在执行
*/
public boolean isRunning() {
return bRunning;
} /**
* @return 返回执行结果
*/
public String getResult() {
Lock readLock = lock.readLock();
readLock.lock();
try {
return new String(result);
} finally {
readLock.unlock();
}
} /**
* 执行命令
*
* @param command eg: cat /sdcard/test.txt
* @param maxTime 最大等待时间 (ms)
* @return this
*/
public ExeCommand run(String command, final int maxTime) {
Log.i("auto", "run command:" + command + ",maxtime:" + maxTime);
if (command == null || command.length() == 0) {
return this;
} try {
process = getRuntime().exec("sh");
} catch (Exception e) {
return this;
}
bRunning = true;
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
os = new DataOutputStream(process.getOutputStream()); try {
//向sh写入要执行的命令
os.write(command.getBytes());
os.writeBytes("\n");
os.flush(); os.writeBytes("exit\n");
os.flush(); os.close();
//如果等待时间设置为非正,就不开启超时关闭功能
if (maxTime > 0) {
//超时就关闭进程
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(maxTime);
} catch (Exception e) {
}
try {
int ret = process.exitValue();
} catch (IllegalThreadStateException e) {
Log.i("auto", "take maxTime,forced to destroy process");
process.destroy();
}
}
}).start();
} //开一个线程来处理input流
final Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
String line;
Lock writeLock = lock.writeLock();
try {
while ((line = successResult.readLine()) != null) {
line += "\n";
writeLock.lock();
result.append(line);
writeLock.unlock();
}
} catch (Exception e) {
Log.i("auto", "read InputStream exception:" + e.toString());
} finally {
try {
successResult.close();
} catch (Exception e) {
Log.i("auto", "close InputStream exception:" + e.toString());
}
}
}
});
t1.start(); //开一个线程来处理error流
final Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
String line;
Lock writeLock = lock.writeLock();
try {
while ((line = errorResult.readLine()) != null) {
line += "\n";
writeLock.lock();
result.append(line);
writeLock.unlock();
}
} catch (Exception e) {
Log.i("auto", "read ErrorStream exception:" + e.toString());
} finally {
try {
errorResult.close();
} catch (Exception e) {
Log.i("auto", "read ErrorStream exception:" + e.toString());
}
}
}
});
t2.start(); Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
//等待执行完毕
t1.join();
t2.join();
process.waitFor();
} catch (Exception e) { } finally {
bRunning = false;
Log.i("auto", "run command process end");
}
}
});
t3.start(); if (bSynchronous) {
t3.join();
}
} catch (Exception e) {
Log.i("auto", "run command process exception:" + e.toString());
}
return this;
} }
讲解一下关键点,首先是启动一个sh进程,当然如果你用的是root的设备,可以使用su。
这个进程包含 input、output、error 三个流,这三个流要处理好,否则可能不能正常结束进程,
另外也存在执行的命令已经结束,但是依然还有input流的情况,也需要处理。
其他请参考代码
使用方式为2种。首先是阻塞方式,这种调用方式会一直阻塞至命令执行完成,返回命令行的输出结果
String str = new ExeCommand().run(cmd, 10000).getResult();
还有一种是异步方式,这种调用方式会直接返回,之后可以使用 getResult() 获取结果,使用 isRunning() 来判断是否完成,比如
ExeCommand cmd = new ExeCommand(false).run("your cmd", 60000);
while(cmd.isRunning())
{
try {
sleep(1000);
} catch (Exception e) {
}
String buf = cmd.getResult();
//do something
}
Android 命令行执行工具类的更多相关文章
- TortoiseSVN 命令 (命令行执行工具)
TortoiseSVN是一个GUI客户端,这个自动化指导为你展示了让TortoiseSVN对话框显示并收集客户输入,如果你希望编写不需要输入的脚本,你应该使用官方的Subversion命令行客户端. ...
- android程序中使用命令行及获得命令行执行后的内容
在开发android项目中,需要在程序中使用命令行执行,获得命令行执行后的结果并做处理. 下面是自己写的一个小例子,供以后参考使用: public String android_command(){ ...
- libvirt 命令行交互工具之virsh
libvirt是当前主流VM最低层库.IBM PowerVM也不例外,libvirt是深入玩虚拟化必须玩转的东西; 简单测试玩玩libvirt 的virsh命令行交互工具, 你我都知libvirt大体 ...
- php 运行linux命令 与 linux下命令行执行php
1.php运行linux命令 exec函数:string exec(string command, string [array], int [return_var]); 执行函数后不输出结果,返回最 ...
- Python中最好用的命令行解析工具:argparse
Python 做为一个脚本语言,可以很方便地写各种工具.当你在服务端要运行一个工具或服务时,输入参数似乎是一种硬需(当然你也可以通过配置文件来实现). 如果要以命令行执行,那你需要解析一个命令行参数解 ...
- 远程shell脚本执行工具类
/** * 远程shell脚本执行工具类 */public class RemoteShellExecutorUtils { private static final Logger logger = ...
- 使用命令行执行jmeter的方法
1. 简介 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资 本文介绍windows下以命令行模式运行的方法. 1.1. 命令介绍 jmeter -n -t & ...
- android 命令行安装apk
有两种方式可以在android模拟器或真机上使用命令行安装apk 一种是使用adb install命令,网上通常是这种方式 另一种是通过android提供的命令,pm install. 需要先进入an ...
- django源码(2.0.2)粗解之命令行执行
前言 django的命令行在整个的django web开发中都会经常用到,而且是必须得用到.所以,能够了解下django的命令行实现其实是非常有帮助的. 如果大家比较关心django命令的详细说明和使 ...
随机推荐
- iOS9支付宝无法调起客户端
1.为了适配 iOS9.0 中的 App Transport Security(ATS)对 http 的限制,这里需要对 支付宝的请求地址 alipay.com 做例外,在 app 对应的 info. ...
- [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别
1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...
- Xamarin技术文档------VS多平台开发
此技术业余时间研究,仅供大家学习参考,不涉及深入研究,有一定开发基础的人员,应该都能较快上手. 一.简介 Xamarin始创于2011年,旨在使移动开发变得难以置信地迅捷和简单.Xamarin的产品简 ...
- wp已死,metro是罪魁祸首!
1.这篇文章肯定会有类似这样的评论:“我就是喜欢wp,我就是喜欢metro,我就是软粉“等类似的信仰论者发表的评论. 2.2014年我写过一篇文章,windows phone如何才能在中国翻身? 我现 ...
- ABP源码分析三十七:ABP.Web.Api Script Proxy API
ABP提供Script Proxy WebApi为所有的Dynamic WebApi生成访问这些WebApi的JQuery代理,AngularJs代理以及TypeScriptor代理.这些个代理就是j ...
- c#文件操作
1.创建文件夹 //using System.IO; Directory.CreateDirectory(%%1); 2.创建文件 //using System.IO; File.Create(% ...
- angular2系列教程(四)Attribute directives
今天我们要讲的是ng2的Attribute directives.顾名思义,就是操作dom属性的指令.这算是指令的第二课了,因为上节课的components实质也是指令. 例子
- 如何部署Zabbix服务端
部署环境 RHEL 6.7 Zabbix-server 2.2.14 安装zabbix官方源 # wget http://repo.zabbix.com/zabbix/2.2/rhel/6/x86_6 ...
- Java豆瓣电影爬虫——小爬虫成长记(附源码)
以前也用过爬虫,比如使用nutch爬取指定种子,基于爬到的数据做搜索,还大致看过一些源码.当然,nutch对于爬虫考虑的是十分全面和细致的.每当看到屏幕上唰唰过去的爬取到的网页信息以及处理信息的时候, ...
- 基于android studio的快捷开发(将持续更新)
对于Android studio作为谷歌公司的亲儿子,自然有它的好用的地方,特别是gradle方式和快捷提示方式真的很棒.下面是我在实际开发中一些比较喜欢用的快速开发快捷键,对于基本的那些就不多说了. ...