如何优雅获的获取不同系统版本中的进程信息

今天来总结一下获取系统中正在运行的进程信息,直接来干货
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;
           }复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值