环境:Android 5.1.1(已root)
最近有一个需求,需要在Android下杀死指定pid的进程。Android原生API提供了几个接口:
(1)android.os.Process.killProcess(int pid) 只能杀死应用自己和启动的子进程
(2)ActivityManager.killBackgroundProcesses(String packageName) 参数只能传包名,不能传pid
但是我们的程序需要杀死指定pid的其他进程。熟悉linux的朋友都知道,kill命令可以进行杀死进程的操作。在Android下可以用Runtime.getRuntime.exec()来执行linux命令。
废话不多说,上代码:
try {
String s = "\n";
String sErr = "\n";
String cmd = "kill -9 " + pid;
Log.d(TAG,"cmd=" + cmd);
Process p = Runtime.getRuntime().exec(cmd);
InputStream is = p.getInputStream();
InputStream ers = p.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
DataInputStream ise = new DataInputStream(ers);
String line = null;
String error = null;
while ((line = reader.readLine()) != null) {
s += line + "\n";
}
Log.d(TAG,"s=" + s);
while((error = ise.readLine()) != null) {
sErr += error + "\n";
}
Log.d(TAG,"sErr=" + sErr);
int result = p.waitFor();
Log.d(TAG,"result=" + result);
is.close();
ers.close();
reader.close();
ise.close();
p.destroy();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
此时从日志可以看到
sErr=kill: 5135: Operation not permitted
应该是没有kill权限的问题。
那把上面代码的kill 前加了一个su,变成
String cmd = "su kill -9 " + pid;
再执行:
sErr=tmp-mksh: tmp-mksh: -9: unknown option
String cmd = "su -c 'kill -9 " + pid + "'";
日志:
sErr=tmp-mksh: kill -9 5135: not found仍然还是失败,昨天到这一步的时候就放弃了,又去找了另外一种实现方式。但是今天在写这篇博客之前,不甘心于失败,又去查了一遍,发现在stackoverflow有一句评论:
+1 nice answer, but adb shell "su -c kill 101" works for me (without '). Thanks :)抱着一试的想法,命令改成了
String cmd = "su -c kill -9 " + pid;执行竟然成功了。有时候成功和失败,很多就差这一次尝试。
接下来说说我昨天用的第二种实现方法,直接上代码:
Process sh = null;
DataOutputStream os = null;
try {
sh = Runtime.getRuntime().exec("su");
os = new DataOutputStream(sh.getOutputStream());
try {
os.writeBytes("kill -9 " + pid + "\n");
Log.d(TAG, "kill -9");
sleep(2000);
} catch (IOException e) {
Log.d(TAG, "kill -9 catch exception");
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
这里是用了一个DataOutputStream的方式,直接把命令写入到流中。先通过su获取root权限,然后直接执行kill命令。
总结:
以上杀其他进程的方式,都是在root的基础上进行的,非root环境暂时没有去探索。
调试过程中,一定要想办法打出错误日志,之前没有把Process的ErrorStream输出,自己每次执行,错误原因都不知道改怎么查。
参考: