一定是我打开的姿势不对——Android下使用kill命令杀死指定进程
16lz
2021-01-23
环境: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
去stackoverflow上查了一下(adb shell operation not permitted),命令需要改成
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输出,自己每次执行,错误原因都不知道改怎么查。
参考:
adb shell operation not permitted
Android中杀进程的几种方法 (1) - killBackgroundProcesses
Android下执行Runtime.getRuntime().exec后返回状态
Android Runtime.getRuntime().exec() 使用方法
更多相关文章
- Android使用AIDL跨进程数据共享
- Android应用程序中执行二进制命令
- Android SDK: adb shell 命令的使用(am、pm、wm、screencap、monk
- AIDL实现Android的进程通信
- Android知识点记录: 使用代码设置 android 上listView的条目的点
- Android 4.1源代码今日将发布
- Android常用的几个命令