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所以這里就不介紹實現方式了。希望這篇文章對你有所幫助。有什么問題可以留言在下方。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM