Android CPU監控想法,思路,核心技術和代碼

核心算法描述:

 

第一步:獲取正在運行的進程, 保存在集合當中 : List<IsRunningAppInfo> appList

 

第二步:讀取總使用的CPU,  路徑在  private static String path = "/proc/stat";

 

第三步:讀取所有運行進程CPU,路徑在  "/proc/" + pid + "/stat";  //pid為進程號

 

第四步:讀取所有運行線程CPU,路徑在 "/proc/" + pid + "/task" + tid +"/stat";   //pid為進程號,tid為線程號

 

第五步:讀取好文件的信息,分別保存在不同集合當中,然後回調回去,存入數據庫(根據需求,可靈活運用),避免一邊讀取文件,一邊保存數據庫當中,不然將耗費大量的時間,產生的誤差特別的大

 

第六步:數據的內容保存好後,到另外一個activity中,從數據庫中讀取數據,並列表顯示出數據。

註意:讀取的時候,可能會碰到讀取文件的內容的時候,還沒有讀好(算所占比例的時候會出現出現“除數為0”),需要定義一個handle,在handle當中讀取數據(讀的過程中,判斷是否數據存儲完畢),並顯示讀取的數據,不能在activity當中不然會出現“AndroidRunTime”錯誤。

 

 

 

獲取正在運行的進程:

 

    /** 
     * 獲取正在運行的進程 
     *  
     * @return 
     */  
    public List<IsRunningAppInfo> queryRunningApp() {  
  
        List<IsRunningAppInfo> listRunApp = new ArrayList<IsRunningAppInfo>();  
        am = (ActivityManager) context  
                .getSystemService(Context.ACTIVITY_SERVICE);  
        List<RunningAppProcessInfo> list = am.getRunningAppProcesses();  
        RunningAppProcessInfo runningPro = null;  
        IsRunningAppInfo appInfo = null;  
        for (int i = 0; i < list.size(); i++) {  
  
            runningPro = list.get(i);  
            appInfo = new IsRunningAppInfo();  
            appInfo.setPid(runningPro.pid);  
            appInfo.setProcessName(runningPro.processName);  
            appInfo.setUid(runningPro.uid);  
            pkgManager(appInfo);  
            listRunApp.add(appInfo);  
        }  
        return listRunApp;  
    }  
  
    /** 
     * 獲取應用程序的 程序名,圖標 
     *  
     * @param appInfo 
     * @throws NameNotFoundException 
     */  
    public void pkgManager(IsRunningAppInfo appInfo) {  
  
        try {  
            PackageManager pm = context.getPackageManager();  
            PackageInfo pkInfo;  
            pkInfo = pm.getPackageInfo(appInfo.getProcessName(), 0);  
            appInfo.setIcon(pkInfo.applicationInfo.loadIcon(pm));  
            appInfo.setAppName(pkInfo.applicationInfo.loadLabel(pm).toString());  
        } catch (NameNotFoundException e) {  
            e.printStackTrace();  
        }  
    }  
  
讀取CPU文件:  
    public void cpuMain() {  
        sqliteHelp  
                .clearAllTableData(new String[] {  
                        Config.TBL_CPUMONITOR_PROCESSCPU,  
                        Config.TBL_CPUMONITOR_TheadCPU,  
                        Config.TBL_CPUMONITOR_TOTALCPU }); // 在讀取文件前清空所有表數據  
        R_W_File rw = new R_W_File();  
        rw.clearFileData(new File(rw.getSdcardPath(), "result.txt"));  
        i = 0;  
        while (i < 2) {  
            queryRunningApp(); // 獲取正在運行的應用程序信息  
            if (i == 0) {  
                readTotalCPU(i); // 捕捉時,總CPU  
            }  
            readProcessCPU(i); // 進程CPU--->線程CPU  
            readThreadCPU(i);  
            i++;  
        }  
    }  
  
    /** 
     * 獲取正在運行的應用程序 
     */  
    protected void queryRunningApp() {  
  
        IsRunningAppProgress pro = new IsRunningAppProgress(context);  
        appList = pro.queryRunningApp();  
    }  
  
    /** 
     * 總CPU使用量 
     */  
    protected void readTotalCPU(int i) {  
  
        AsyncTask_TotalCPU taskTotalCPU = new AsyncTask_TotalCPU(context);  
        taskTotalCPU.execute(i, null, null);  
    }  
  
    /** 
     * 進程CPU 
     */  
    protected void readProcessCPU(int i) {  
        AsyncTask_ProgressCPU taskProcessCPU = null;  
        taskProcessCPU = new AsyncTask_ProgressCPU(new ProcessCallback(),  
                appList);  
        taskProcessCPU.execute(i, null, null);  
    }  
  
    /** 
     * 線程CPU 
     */  
    protected void readThreadCPU(int i) {  
        AsyncTask_TheadCPU taskThreadCPU = new AsyncTask_TheadCPU(  
                new ThreadCallback(), appList);  
        taskThreadCPU.execute(i, null, null);  
    }  
  
    /** 
     * 回調方法 
     */  
    class ThreadCallback implements ICallbacks {  
  
        @Override  
        public <T> void call(T t1, T t2) {  
            if ((Integer) t2 == 1) {  
                readTotalCPU(1); // 捕捉時,總CPU  
            }  
            @SuppressWarnings("unchecked")  
            Map<String[], IsRunningAppInfo> saveThreadCPUMap = (Map<String[], IsRunningAppInfo>) t1;  
            saveThreadData(saveThreadCPUMap, (Integer) t2);  
        }  
    }  
  
    /** 
     * 回調方法 
     */  
    class ProcessCallback implements ICallbacks {  
  
        @Override  
        public <T> void call(T t1, T t2) {  
            @SuppressWarnings("unchecked")  
            Map<String[], IsRunningAppInfo> saveProCPUMap = (Map<String[], IsRunningAppInfo>) t1;  
            saveProData(saveProCPUMap, (Integer) t2);  
        }  
    }  
  
    public void saveThreadData(  
            Map<String[], IsRunningAppInfo> saveThreadCPUMap, int j) {  
  
        Set<String[]> key = saveThreadCPUMap.keySet();  
        Iterator<String[]> it = key.iterator();  
        String[] str = null;  
        IsRunningAppInfo appInfo = null;  
        ContentValues cv = null;  
        while (it.hasNext()) {  
            str = it.next();  
            appInfo = saveThreadCPUMap.get(str);  
            cv = new ContentValues();  
            cv.put("processName", appInfo.getProcessName());  
            cv.put("pid", appInfo.getPid());  
            cv.put("tid", Long.valueOf(str[0]));  
            cv.put("utime", Long.valueOf(str[13]));  
            cv.put("stime", Long.valueOf(str[14]));  
            cv.put("numTimes", j);  
            sqliteHelp.append(Config.TBL_CPUMONITOR_TheadCPU, cv);  
        }  
        if (j == 1) {  
            writeData();  
        }  
    }  
  
    /** 
     * 保存進程數據 
     *  
     * @param saveProCPUMap 
     * @param j 
     */  
    private void saveProData(Map<String[], IsRunningAppInfo> saveProCPUMap,  
            int j) {  
  
        Set<String[]> key = saveProCPUMap.keySet();  
        Iterator<String[]> it = key.iterator();  
        String[] str = null;  
        IsRunningAppInfo runApp = null;  
        ContentValues cv = null;  
        while (it.hasNext()) {  
            str = it.next();  
            runApp = saveProCPUMap.get(str);  
            cv = new ContentValues();  
            if (runApp.getIcon() == null) {  
                cv.put("icon",  
                        FormatImage.getInstace().getDrawableToByte(  
                                context.getResources().getDrawable(  
                                        R.drawable.ic_launcher_default)));  
            } else  
                cv.put("icon",  
                        FormatImage.getInstace().getDrawableToByte(  
                                runApp.getIcon()));  
            if (runApp.getAppName() == null || runApp.getAppName().equals("")) {  
                cv.put("appName", runApp.getProcessName());  
            } else  
                cv.put("appName", runApp.getAppName());  
            cv.put("processName", runApp.getProcessName());  
            cv.put("pid", runApp.getPid());  
            cv.put("utime", str[13]);  
            cv.put("stime", str[14]);  
            cv.put("cutime", str[15]);  
            cv.put("cstime", str[16]);  
            cv.put("numTimes", j);  
            sqliteHelp.append(Config.TBL_CPUMONITOR_PROCESSCPU, cv);  
        }  
        if (j == 1) {  
            writeData();  
        }  
    }  
  
    public void writeData() {  
        try {  
            R_W_File files = new R_W_File();  
            File mFile = new File(files.getSdcardPath(), "result.txt");  
            files.writeFileDataAtTail(mFile, "1");  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}  
顯示CPU列表數據:  
public View getView(int position, View convertView, ViewGroup parent) {  
  
        ProcessCPU pro = list.get(position);  
  
        if (convertView == null) {  
            convertView = inflater.inflate(layoutId, null);  
            appView = new AppView(convertView);  
            convertView.setTag(appView);  
        } else {  
            appView = (AppView) convertView.getTag();  
        }  
        appView.pkgName.setText(pro.getProcessName());  
        appView.appIcon.setBackgroundDrawable(pro.getIcon()); // 圖標  
        appView.appName.setText(pro.getAppName()); // 應用名  
        appView.pb.setMax(100);  
        if (pro.getProcessName().equals("system"))  
            Log.e("systemValue:" + pro.getUtime() + "  ==totalCPU:" + totalCPU);  
        double schedule = Double.valueOf(String.format("%.2f", pro.getUtime()  
                * 100.00 / totalCPU));  
        appView.pb.setProgress((int) schedule);  
        appView.tvPb.setText("" + schedule + "%");  
  
        return convertView;  
    }  
handle中讀取並顯示數據:  
  
    @Override  
    public void handleMessage(Message msg) {  
        super.handleMessage(msg);  
  
        dialog = (Dialog) msg.obj;  
  
        queryTotalCPU();  
        queryProcessList();  
  
        if (adapterCpuChart == null) {  
            adapterCpuChart = new Adapter_cpu_chart(context,  
                    R.layout.adapter_cpu_chart, list, totalCPU);  
        }  
        lvChart.setAdapter(adapterCpuChart);  
        adapterCpuChart.notifyDataSetChanged();  
        pbBar.closeDialogProgressBar(dialog);  
    }  
  
    /** 
     * 查找總共CPU時間片 每次進行數據查詢的時候,將表中的數據重新請空 
     */  
    public void queryTotalCPU() {  
  
        sql = "select (max(num1)-min(num1)) as total from "  
                + "(select (t.user+t.nice+t.system+t.iowait+t.irq+t.softirq+t.stealstolen+t.guest) as num1 "  
                + "from TotalCPU t)";  
        cursor = sqliteHelp.query(sql);  
        int index = -1;  
        long allValue = -1;  
        long ownValue = -1;  
        long ownThreadCPU = -1;  
        if (cursor.moveToFirst()) {  
            index = cursor.getColumnIndex("total");  
            allValue = cursor.getLong(index);  
        }  
        sqliteHelp.closeDb();  
        sql = "select  (max(num2)-min(num2)) as ownCPU from (select (p.utime+p.stime+p.cstime+p.cutime) as num2 "  
                + "from ProcessCPU p "  
                + "where p.processName='"  
                + pkgName  
                + "') ";  
        cursor = sqliteHelp.query(sql);  
        if (cursor.moveToFirst()) {  
            index = cursor.getColumnIndex("ownCPU");  
            ownValue = cursor.getLong(index);  
        }  
        sqliteHelp.closeDb();  
  
        sql = "select  max(num3)-min(num3) as ownThreadCPU "  
                + "from (select (t.utime+t.stime) as num3 "  
                + "from ThreadCPU t " + "where t.processName='" + pkgName  
                + "') ";  
        cursor = sqliteHelp.query(sql);  
        if (cursor.moveToFirst()) {  
            index = cursor.getColumnIndex("ownThreadCPU");  
            ownThreadCPU = cursor.getLong(index);  
        }  
        sqliteHelp.closeDb();  
  
        totalCPU = (allValue - ownValue - ownThreadCPU);  
        Log.e("allValue:" + allValue + "  " + " ownValue:" + ownValue  
                + "  ownThreadCPU" + ownThreadCPU);  
    }  
  
    /** 
     * 查找所有進程的CPU時間片 
     */  
    public void queryProcessList() {  
        sql = "select p.processName,p.appName,p.icon,sum(temp.utime) as utime "  
                + "from (select processName,(max(utime)-min(utime)) as utime "  
                + "from (select processName,appName,icon, (utime+stime+cutime+cstime) as utime "  
                + "from ProcessCPU where processName <> '"  
                + pkgName  
                + "' and numTimes=0 "  
                + "union all "  
                + "select processName,appName,icon, (utime+stime+cutime+cstime) as utime "  
                + "from ProcessCPU where processName <> '"  
                + pkgName  
                + "' and numTimes=1 ) "  
                + "group by processName "  
                + "union all select processName,(max(utime)-min(utime)) as utime "  
                + "from (select processName, sum(utime+stime) as utime "  
                + "from ThreadCPU where processName <> '"  
                + pkgName  
                + "' and numTimes=0 "  
                + "group by processName union all select processName, sum(utime+stime) as utime "  
                + "from ThreadCPU where processName <> '"  
                + pkgName  
                + "' and numTimes=1 "  
                + "group by processName) group by processName) as temp,ProcessCPU p "  
                + "where p.processName=temp.processName group by p.processName "  
                + "order by utime desc limit 10";  
        list = new ArrayList<ProcessCPU>();  
        cursor = sqliteHelp.query(sql);  
        ProcessCPU proCPU = null;  
        if (cursor.moveToFirst()) {  
            do {  
                proCPU = new ProcessCPU();  
                int processName = cursor.getColumnIndex("processName");  
                int appName = cursor.getColumnIndex("appName");  
                int icon = cursor.getColumnIndex("icon");  
                int utime = cursor.getColumnIndex("utime");  
                proCPU.setAppName(cursor.getString(appName));  
                proCPU.setProcessName(cursor.getString(processName));  
                proCPU.setIcon(FormatImage.getInstace().getByteToDrawable(  
                        cursor.getBlob(icon)));  
                proCPU.setUtime(cursor.getLong(utime));  
                list.add(proCPU);  
            } while (cursor.moveToNext());  
        }  
        sqliteHelp.closeDb();  
    }  
  
讀取進程CPU:  
public void readFile() {  
  
        String[] str = null;  
        for (int i = 0; i < list.size(); i++) {  
  
            runApp = list.get(i);  
            file = new File(getPath(runApp.getPid()));  
            try {  
                fis = new FileInputStream(file);  
                br = new BufferedReader(new InputStreamReader(fis));  
                String readLine;  
                while ((readLine = br.readLine()) != null) {  
                    str = readLine.split(" ");  
                }  
                br.close();  
                fis.close();  
            } catch (FileNotFoundException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            saveProCPUMap.put(str, runApp);  
        }  
    }  
  
    /** 
     * 獲取每個進程的 文件路徑 
     *  
     * @param pid 
     * @return 
     */  
    public String getPath(long pid) {  
        return "/proc/" + pid + "/stat";  
    }  
讀取線程CPU:  
    public void queryThreadCPU(List<IsRunningAppInfo> list) throws IOException {  
        for (int i = 0; i < list.size(); i++) {  
            IsRunningAppInfo appInfo = list.get(i);  
            queryThreadCPU(appInfo);  
        }  
    }  
  
    /** 
     * 根據每一個pid獲取CPU使用率 
     *  
     * @param pid 
     * @return 
     * @throws IOException 
     */  
    public void queryThreadCPU(IsRunningAppInfo appInfo) throws IOException {  
  
        path = "/proc/" + appInfo.getPid() + "/task";  
        file = new File(path);  
        if (file.exists() && file != null) {  
  
            files = file.listFiles();  
            if (files != null) {  
                queryThreadCPU(files, appInfo);  
            }  
        }  
    }  
  
    /** 
     * 查詢某一個進程的 線程CPU使用情況 
     *  
     * @param files 
     * @return 
     * @throws IOException 
     */  
    private void queryThreadCPU(File[] files, IsRunningAppInfo appInfo)  
            throws IOException {  
        String readLine;  
        String[] tStr = null;  
        for (int i = 0; i < files.length; i++) {  
            File f = files[i];  
            path = f.getPath() + "/stat";  
  
            file = new File(path);  
            fis = new FileInputStream(file);  
            br = new BufferedReader(new InputStreamReader(fis));  
            while ((readLine = br.readLine()) != null) {  
                tStr = readLine.split(" ");  
            }  
        }  
        saveThreadCPUMap.put(tStr, appInfo);  
    }  
  
    @Override  
    protected void onPostExecute(Void result) {  
        super.onPostExecute(result);  
    }  
讀取總CPU:  
    public Long readFile() {  
  
        String[] str = null;  
        file = new File(path);  
        try {  
            fis = new FileInputStream(file);  
            br = new BufferedReader(new InputStreamReader(fis));  
            String readLine;  
            if ((readLine = br.readLine()) != null) {  
                str = readLine.split(" ");  
            }  
            br.close();  
            fis.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return changeArray(str);  
    }  
  
    private Long changeArray(String[] str) {  
        Log.e("長度:" + str.length);  
        ContentValues cv = new ContentValues();  
        cv.put("user", Long.valueOf(str[2]));  
        cv.put("nice", Long.valueOf(str[3]));  
        cv.put("system", Long.valueOf(str[4]));  
        cv.put("idle", Long.valueOf(str[5]));  
        cv.put("iowait", Long.valueOf(str[6]));  
        cv.put("irq", Long.valueOf(str[7]));  
        cv.put("softirq", Long.valueOf(str[8]));  
        cv.put("stealstolen", Long.valueOf(str[9]));  
        cv.put("guest", Long.valueOf(str[10]));  
        cv.put("numTimes", i);  
        return sqliteHelp.append(Config.TBL_CPUMONITOR_TOTALCPU, cv);  
    }  

 

 

發佈留言