Android CPU监控想法,思路,核心技术和代码

513次 2013-11-20
核心算法描述:   第一步:获取正在运行的进程, 保存在集合当中 : List 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 queryRunningApp() {  
  
        List listRunApp = new ArrayList();  
        am = (ActivityManager) context  
                .getSystemService(Context.ACTIVITY_SERVICE);  
        List 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  void call(T t1, T t2) {  
            if ((Integer) t2 == 1) {  
                readTotalCPU(1); // 捕捉时,总CPU  
            }  
            @SuppressWarnings("unchecked")  
            Map saveThreadCPUMap = (Map) t1;  
            saveThreadData(saveThreadCPUMap, (Integer) t2);  
        }  
    }  
  
    /** 
     * 回调方法 
     */  
    class ProcessCallback implements ICallbacks {  
  
        @Override  
        public  void call(T t1, T t2) {  
            @SuppressWarnings("unchecked")  
            Map saveProCPUMap = (Map) t1;  
            saveProData(saveProCPUMap, (Integer) t2);  
        }  
    }  
  
    public void saveThreadData(  
            Map saveThreadCPUMap, int j) {  
  
        Set key = saveThreadCPUMap.keySet();  
        Iterator 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 saveProCPUMap,  
            int j) {  
  
        Set key = saveProCPUMap.keySet();  
        Iterator 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 "  
                + "u nion all "  
                + "select processName,appName,icon, (utime+stime+cutime+cstime) as utime "  
                + "from ProcessCPU where processName <>   
                + pkgName  
                +  and numTimes=1 ) "  
                + "group by processName "  
                + "u nion 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 u nion 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();  
        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 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);  
    }