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命令的详细说明和使 ...
随机推荐
- Linux学习日记-使用EF6 Code First(四)
一.在linux上使用EF 开发环境 VS2013+mono 3.10.0 +EF 6.1.0 先检测一下EF是不是6的 如果不是 请参阅 Linux学习日记-EF6的安装升级(三) 由于我的数据库 ...
- Linux CentOS7通过yum命令安装Mono(尝先安装模式)
前言 经过尝试网上各种安装mono的技术贴,这个安装过程经历了大约2周,尝试了各个版本,几目前博客所描述的所有安装方式.以下内容的安装方式可以为你尝试不同版本的mono.并非正式环境安装标准方式安装. ...
- 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...
- 实现了一个百度首页的彩蛋——CSS3 Animation简介
在百度搜索中有这样一个彩蛋:搜索“旋转”,“跳跃”,“反转”等词语,会出现相应的动画效果(搜索“反转”后的效果).查看源码可以发现,这些效果正是通过CSS3的animation属性实现的. 实现这个彩 ...
- ASP.NET Web API Model-ModelBinder
ASP.NET Web API Model-ModelBinder 前言 本篇中会为大家介绍在ASP.NET Web API中ModelBinder的绑定原理以及涉及到的一些对象模型,还有简单的Mod ...
- 如何开发一个简单的HTML5 Canvas 小游戏
原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...
- 使用xUnit,EF,Effort和ABP进行单元测试(C#)
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 本篇目录 介绍 创建测试项目 准备测试基类 创建第一个测试 测试异常 在测试中使用仓储 测试异步方法 小结 介绍 在这篇博客中,我 ...
- python学习 异常
#===========================常见异常 ===================== #print(a);#NameError: name 'a' is not defined ...
- 在linux平台实现atosl
➠更多技术干货请戳:听云博客 序言 怎么在linux 平台下实现一个类似于mac 平台下的 atos 工具( iOS 符号化解析)? 分析问题 在github上找到了几年前的开源实现,[https:/ ...
- ASP.NET MVC系列:Model
1. Model任务 Model负责通过数据库.AD(Active Directory).Web Service及其他方式获取数据,以及将用户输入的数据保存到数据库.AD.Web Service等中. ...