zoukankan      html  css  js  c++  java
  • Android开发之获取系统所有进程信息。

      最近在做一个app,有一个进程管理模块用于管理系统中正在运行的进程,并且可以关闭进程进行加速手机的功能,基本把它实现了出来。界面的效果都是自己写的,虽然有BUG,但是基本上能满足需求,后期我会改进BUG。好了,来看看效果:

    1.获取系统的可用内存和总内存。

    获取系统内存中应用的信息,需要用到ActivityManager这个类,然而当你用这个类拿数据的时候你会发现,拿到的数据不正确。用这个类的API获取系统的总内存和可用内存会出现数据不正确的情况。除了这个类,Android手机中有文件描述了这些信息——/proc/meminfo。meminfo文件中详细的记录了安卓手机的一些数据,包括可用内存和总内存。附上代码:

     public static long getTotalMemSize() {
            long size=0;
            File file = new File("/proc/meminfo");
            try {
                BufferedReader buffer = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                String memInfo = buffer.readLine();
                int startIndex = memInfo.indexOf(":");
                int endIndex = memInfo.indexOf("k");
                memInfo = memInfo.substring(startIndex + 1, endIndex).trim();
                size = Long.parseLong(memInfo);
                size *= 1024;
                buffer.close();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
            return size;
        }
    
        public static long getAviableMemSize() {
            long size=0;
            File file = new File("/proc/meminfo");
            try {
                BufferedReader buffer = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                 String memInfos=new String();
                int i=0;
                while ((memInfos=buffer.readLine())!=null){
                   i++;
                    if (i==2){
                        memInfo = memInfos;
                    }
    
                }
                int startIndex = memInfo.indexOf(":");
                int endIndex = memInfo.indexOf("k");
                memInfo = memInfo.substring(startIndex + 1, endIndex).trim();
                size = Long.parseLong(memInfo);
                size *= 1024;
                buffer.close();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
    
            return size;
        }

    操作很简单分别是读取第一行的数据和第二行的数据,将字符串分去出,将所得值乘以1024变为byte类型。

    2.获取内存中运行应用的信息

    首先,自然要有一个Bean文件用于存储这些信息,之后通过ActivityManager的getRunningAppProcesses()方法得到一个RunningAppProcessInfo的List。便利这个List去除我们想要的数据,存在我们的Bean文件夹中。

      public static List<TaskBean> getAllTask() {
            List<TaskBean>taskList=new ArrayList<>();
            List<ActivityManager.RunningAppProcessInfo>runList=UIUtils.getActManager().getRunningAppProcesses();
            try {
                for (ActivityManager.RunningAppProcessInfo r:runList) {
                    TaskBean taskBean = new TaskBean();
                    String processName = r.processName;
                    taskBean.setPackageName(processName);
                    PackageInfo packageInfo = UIUtils.getPacManager().getPackageInfo(processName, 0);
                    taskBean.setIcon(packageInfo.applicationInfo.loadIcon(UIUtils.getPacManager()));
                    taskBean.setName(packageInfo.applicationInfo.loadLabel(UIUtils.getPacManager()).toString());
                    Debug.MemoryInfo[] processInfo=UIUtils.getActManager().getProcessMemoryInfo(new int[]{r.pid});
                    taskBean.setMemSize(processInfo[0].getTotalPrivateDirty()*1024);
                    if ((packageInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM)!=0){
                        taskBean.setSystem(true);
                    }else {
                        taskBean.setUser(true);
                    }
                    if (taskList != null) {
                        taskList.add(taskBean);
                        for (int i=0;i<taskList.size();i++) {
                            if (taskList.get(i).getPackageName().equals(Constants.PACKAGE_INFO)){
                                taskList.remove(i);
                            }
                        }
                    }
                }
                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                }
    
            return taskList;
        }

    好了,大功告成。当你开开心心的拿到手机上调试的时候你会发现,一个数据都没有。原来,在Android5.0之后,谷歌处于完全考虑已经弃用了通过如上方法拿到进程中的信息。那么又应该怎么做呢?

     public static List<TaskBean> getTaskInfos() {
            List<AndroidAppProcess> processInfos = ProcessManager.getRunningAppProcesses();
    
            List<TaskBean> taskinfos = new ArrayList<TaskBean>();
            // 遍历运行的程序,并且获取其中的信息
            for (AndroidAppProcess processInfo : processInfos) {
                TaskBean taskinfo = new TaskBean();
                // 应用程序的包名
                String packname = processInfo.name;
                taskinfo.setPackageName(packname);
                // 湖区应用程序的内存 信息
                android.os.Debug.MemoryInfo[] memoryInfos = UIUtils.getActManager()
                        .getProcessMemoryInfo(new int[] { processInfo.pid });
                long memsize = memoryInfos[0].getTotalPrivateDirty() * 1024L;
                taskinfo.setMemSize(memsize);
                taskinfo.setPackageName(processInfo.getPackageName());
                try {
                    // 获取应用程序信息
                    ApplicationInfo applicationInfo = UIUtils.getPacManager().getApplicationInfo(
                            packname, 0);
                    Drawable icon = applicationInfo.loadIcon(UIUtils.getPacManager());
                    taskinfo.setIcon(icon);
                    String name = applicationInfo.loadLabel(UIUtils.getPacManager()).toString();
                    taskinfo.setName(name);
    
                    if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        // 用户进程
                        taskinfo.setUser(true);
                    } else {
                        // 系统进程
                        taskinfo.setSystem(true);
                    }
                } catch (PackageManager.NameNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    // 系统内核进程 没有名称
                    taskinfo.setName(packname);
                    Drawable icon = UIUtils.getContext().getResources().getDrawable(
                            R.drawable.ic_launcher);
                    taskinfo.setIcon(icon);
                }
                if (taskinfo != null) {
                    taskinfos.add(taskinfo);
                    for (int i=0;i<taskinfos.size();i++) {
                        if (taskinfos.get(i).getPackageName().equals(Constants.PACKAGE_INFO)){
                            taskinfos.remove(i);
                        }
                    }
                }
            }
            return taskinfos;
        }

    好了,接下来只需要判断安装的版本就可以了:

    int sysVersion = Integer.parseInt(Build.VERSION.SDK);
    taskList = sysVersion > 21 ? TaskManagerEngine.getTaskInfos() : TaskManagerEngine.getAllTask();

    好了,大功告成。数据就能正常拿到了。关于这个效果,我实现下来比较复杂,用了属性动画和补间动画,依赖于Material Design,封装的不是很好,也有BUG所以这里就不介绍实现方式了。希望这篇文章对你有所帮助。有什么问题可以留言在下方。

  • 相关阅读:
    2019年11月28日开发手记
    2019年11月26日开发手记
    2019年11月25日开发手记
    2019年11月24日开发手记
    2019年11月23日开发手记
    R学习
    python学习目录
    自动化测试appium
    python爬虫的进阶用法
    asyncio
  • 原文地址:https://www.cnblogs.com/lovelyYakir/p/5886961.html
Copyright © 2011-2022 走看看