今天来总结一下获取系统中正在运行的进程信息,直接来干货
4.X系统中:
public List<ProcessInfo> getAllRunningAppProcessInfo() {
ActivityManager am = (ActivityManager) GTApp.getContext()
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcessList = am
.getRunningAppProcesses();
List<ProcessInfo> ret = new ArrayList<ProcessInfo>();
for (ActivityManager.RunningAppProcessInfo info : appProcessList)
{
ProcessInfo processInfo = new ProcessInfo(info.pid, info.processName, -1, info.uid);
ret.add(processInfo);
}
return ret;
}复制代码
5.x系统中:
5.0系统以上am.getRunningAppProcesses()方法就不能获取系统正在运行进程的相关信息,只能返回本应用程序的进程。我们可以通过ps的相关方法获取。
1.ps |grep zygote命令获取android应用进程的父进程Zygote的进程号
从Android 4.4宣布支持64位系统以来,各终端方案厂商逐步推出了各自的64位soc解决方案。Google为了兼容之前32位系统的应用,在64位系统上也实现了对32位应用的支持,在64系统中会同时存在两个Zygote进程——zygote和zygote64,分别对应32位和64位应用。所以,要进行App的32/64位检测,只需要看它的父进程是哪个Zygote即可
public List<ProcessInfo> getAllRunningAppProcessInfo() {
List<ProcessInfo> appProcessList = new ArrayList<ProcessInfo>();
// 先取Android应用进程的父进程zygote的进程号,64位app对应的是zygote64
int zygotePid = -1;
int zygotePid64 = -1;
BufferedReader readerZ = null;
try {
ProcessBuilder execBuilderZ = null;
execBuilderZ = new ProcessBuilder("sh", "-c", "ps |grep zygote");
execBuilderZ.redirectErrorStream(true);
Process execZ = execBuilderZ.start();
InputStream isZ = execZ.getInputStream();
readerZ = new BufferedReader(
new InputStreamReader(isZ));
String lineZ = "";
while ((lineZ = readerZ.readLine()) != null) {
String[] arrayZ = lineZ.trim().split("\\s+");
if (arrayZ.length >= 9) {
if (arrayZ[8].equals("zygote"))
{
zygotePid = Integer.parseInt(arrayZ[1]);
}
else if (arrayZ[8].equals("zygote64"))
{
zygotePid64 = Integer.parseInt(arrayZ[1]);
}
}
}
}
catch (Exception e) {
e.printStackTrace();
} finally {
FileUtil.closeReader(readerZ);
}
if (zygotePid < 0)
{
return appProcessList;
}复制代码
2.正式的获取正在运行的进程信息:
BufferedReader reader = null;
try {
ProcessBuilder execBuilder = null;
execBuilder = new ProcessBuilder("sh", "-c", "ps |grep u0_a");
execBuilder.redirectErrorStream(true);
Process exec = null;
exec = execBuilder.start();
InputStream is = exec.getInputStream();
reader = new BufferedReader(
new InputStreamReader(is));
String line = "";
while ((line = reader.readLine()) != null) {
//使用多个空格分隔
String[] array = line.trim().split("\\s+");
if (array.length >= 9) {
//大于10000的uid会以u0_a开头,10021显示为u0_a21
//非系统应用的名称已U0_a开头,用户的uid都大于10000,
int uid = Integer.parseInt(array[0].substring(4)) + 10000;
int pid = Integer.parseInt(array[1]);
int ppid = Integer.parseInt(array[2]);
// 过滤掉系统子进程,只留下父进程是zygote的进程
if (ppid == zygotePid || ppid == zygotePid64)
{
ProcessInfo pi = new ProcessInfo(pid, array[8], ppid, uid);
appProcessList.add(pi);
procInfoCache.put(array[8], pi);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally
{
FileUtil.closeReader(reader);
}
return appProcessList;
}复制代码
6.x以上系统:
static class Process6x extends Process5x
{
// 有的6.x系统,在ps命令的策略上和5.x还是一样的,此时应该用5x的策略
static boolean isLike5x = false;
@Override
public List<ProcessInfo> getAllRunningAppProcessInfo() {
if (isLike5x)
{
return super.getAllRunningAppProcessInfo();
}
List<ProcessInfo> appProcessList = new ArrayList<ProcessInfo>();
// 正式取可用的Android进程
BufferedReader reader = null;
try {
ProcessBuilder execBuilder = null;
execBuilder = new ProcessBuilder("sh", "-c", "ps");
execBuilder.redirectErrorStream(true);
Process exec = null;
exec = execBuilder.start();
InputStream is = exec.getInputStream();
reader = new BufferedReader(
new InputStreamReader(is));
String line = "";
while ((line = reader.readLine()) != null) {
String[] array = line.trim().split("\\s+");
if (array.length >= 9) {
// 先屏蔽常用的shell命令进程
if (array[8].equals("su") || array[8].equals("sh")
|| array[8].equals("sush") || array[8].equals("ps"))
{
continue;
}
int uid = -1;
try
{
uid = Integer.parseInt(array[0].substring(4)) + 10000;
}
catch (Exception e)
{
// 如果异常了,说明取到了系统进程信息,则判定为该6.x系统的策略和5.x一致,应尝试5.x的策略
isLike5x = true;
FileUtil.closeReader(reader); // 提前关闭流
return super.getAllRunningAppProcessInfo();
}
int pid = Integer.parseInt(array[1]);
int ppid = Integer.parseInt(array[2]);
ProcessInfo pi = new ProcessInfo(pid, array[8], ppid, uid);
appProcessList.add(pi);
super.procInfoCache.put(array[8], pi);
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally
{
FileUtil.closeReader(reader);
}
return appProcessList;
}复制代码