Android开发APP过程中,对于某些功耗较大的功能需要实时监测CPU占用(CPU作为手机功耗的核心模块,几乎占了性能消耗的大数,因此监控了CPU基本也就了解了当前手机的运行状况)。

目前市面上的一些监控CPU的程序有的是针对某些机型的CPU(比如高通针对骁龙芯片的Trepen,MTK针对联发科芯片的Mali),有的只能监控整体CPU,而无法针对某个应用的占用进行监控(比如PerfMon);

而Android studio自带的Android Profiler工具在更新到某个版本之后就只支持API 21之后的机型了,比较旧的机型无法使用;更为严重的是,在本人实测多款机型中发现,开启Android Profiler会开启一个debug监控进程,这个监控进程对于某些机型(小米居多)的真实CPU占用是有影响的,一开启的CPU占用会迅速升高,甚至会出现可见性的卡顿情况;

针对这种难题,本人在查询多方资料,选择不影响实际性能的方式,实现了一个针对全机型适用的CPU监测工具,github地址:https://github.com/duguju/AndroidCPUCollector

核心类是CPUCollector:

/** Copyright (C) 2019 jjoeyang. All Rights Reserved.*/
package com.yzz.cpucollector;import android.util.Log;import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;/*** CPU占用统计类* 单例,进入APP时通过setPkgName()设置应用包名,调用getCPURate()即可输出CPU统计信息,退出时调用release()** Created by jjoeyang on 19/5/6*/
public class CPUCollector {public static final String TAG = CPUCollector.class.getSimpleName();private String mPkgName = null;private String mLastCPU = "";private Thread mCpuThread;private boolean enableCPU = true;private boolean isRunning = false;private boolean doCollect = false;private static final String COMMAND_SH = "sh";private static final String COMMAND_LINE_END = "\n";private static final String COMMAND_EXIT = "exit\n";private int maxFrameCount = 5; // 统计的总次数,可修改private int resultFrameTimes = 0; // 统计次数private double resultAVGValue;private String mAvgCPUValue;private static CPUCollector mInstance = null;private CPUCollector() {if (mCpuThread == null) {mCpuThread = new Thread(new Runnable() {@Overridepublic void run() {while (enableCPU) {if (doCollect && !isRunning) {doCollect = false;isRunning = true;mLastCPU = getCPUFromTopCMD();isRunning = false;} else {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}});mCpuThread.setName("CpuCollectorThread");mCpuThread.start();}}public static synchronized CPUCollector getInstance() {if (mInstance == null) {mInstance = new CPUCollector();}return mInstance;}public void setPkgName(String pkgName) {mPkgName = pkgName;}public String getCPURate() {if (!isRunning && mPkgName != null) {doCollect = true;}return mLastCPU;}public String getAvgCPU() {return mAvgCPUValue;}public void release() {mPkgName = null;mAvgCPUValue = null;enableCPU = false;mCpuThread = null;}private String getCPUFromTopCMD() {String cpu = "";List<String> result = execute("top -n 1 -s cpu | grep " + mPkgName);if (result != null && result.size() > 0) {String r = result.get(0);if (r != null && r.contains("%")) {int end = r.indexOf("%");int start = -1;for (int i = end; i >= 0; i--) {if (Character.isWhitespace(r.charAt(i))) {start = i;break;}}if (start >= 0) {cpu = r.substring(start, end);calculateAVGValue(Double.parseDouble(cpu));}}}return cpu;}/*** 执行单条命令** @param command* @return*/private List<String> execute(String command) {return execute(new String[]{command});}/*** 可执行多行命令(bat)** @param commands* @return*/private List<String> execute(String[] commands) {List<String> results = new ArrayList<String>();int status = -1;if (commands == null || commands.length == 0) {return null;}Process process = null;BufferedReader successReader = null;BufferedReader errorReader = null;StringBuilder errorMsg = null;DataOutputStream dos = null;try {process = Runtime.getRuntime().exec(COMMAND_SH);dos = new DataOutputStream(process.getOutputStream());for (String command : commands) {if (command == null) {continue;}dos.write(command.getBytes());dos.writeBytes(COMMAND_LINE_END);dos.flush();}dos.writeBytes(COMMAND_EXIT);dos.flush();status = process.waitFor();errorMsg = new StringBuilder();successReader = new BufferedReader(new InputStreamReader(process.getInputStream()));errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));String lineStr;while ((lineStr = successReader.readLine()) != null) {results.add(lineStr);}while ((lineStr = errorReader.readLine()) != null) {errorMsg.append(lineStr);}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {if (dos != null) {dos.close();}if (successReader != null) {successReader.close();}if (errorReader != null) {errorReader.close();}} catch (IOException e) {e.printStackTrace();}if (process != null) {process.destroy();}}Log.d(TAG, (String.format(Locale.CHINA, "execute command end, errorMsg:%s, and status %d: ",errorMsg, status)));return results;}private void calculateAVGValue(double resultTime) {if (resultFrameTimes >= maxFrameCount) {if (resultFrameTimes == maxFrameCount) {resultFrameTimes++;}mAvgCPUValue = String.format("%.2f", resultAVGValue);resultFrameTimes = 0;resultAVGValue = 0;return;}resultFrameTimes++;double allResultTime = (resultFrameTimes - 1) * resultAVGValue;resultAVGValue = (allResultTime + resultTime) / resultFrameTimes;}
}

核心原理就是通过代码方式,固定间隔调用adb监控CPU的命令(adb shell top -m 100 -n 1 -s cpu),从而输出当前应用的CPU占用情况;支持获取当前占用并进行N帧的平均统计。具体API调用及使用方式可参考github中的Demo

第一版是log输出的CPU信息,Demo中过滤以下log:

05-13 12:03:48.914 12240-12240/com.yzz.cpucollector E/duguju-cpu: 当前CPU占用: 4%  平均:5.2%

今后会做一些界面、操作优化等更新工作,敬请期待~

Android应用CPU实时监控工具-全机型适用相关推荐

  1. android phone电脑驱动下载,全机型Android Phone驱动及安装教程(XP,Vista,Win7).pdf

    全机型Android Phone驱动及安装教程(XP,Vista,Win7) HTC Android( ) Android Phone 安卓 全机型 驱动及安 装教程(XP,Vista,Win7 ) ...

  2. android 卸载预装软件,安卓全机型卸载预装软件免费版下载_安卓全机型卸载预装软件最新版下载_3DM软件...

    <安卓全机型卸载预装软件>这是一款可以删除安卓手机内置软件的工具,让安卓手机用户可以有一个自己喜欢的桌面.软件操作起来很方便,有需要的快来下载吧! 使用方法 1.首先,大家打开手机设置,狂 ...

  3. 超级壁纸android,【教程】MIUI最新超级壁纸安卓全机型安装指南

    在2020年4月,小米正式发布了 MIUI 12 系统,带来了广受欢迎的超级壁纸,那个时候首发只有地球和火星这2个超级壁纸,极客君也是在第一时间分享了这2个超级壁纸的安卓全机型安装教程. 1个月前 M ...

  4. zuk如将手机更新到Android10,ZUI新升级:ZUK宣布支持全机型升级Android N系统

    原标题:ZUI新升级:ZUK宣布支持全机型升级Android N系统 安卓中国5月31日消息,联想ZUK今天的整场发布会基本都基于ZUI系统的更新而成,而ZUK Z2其实只是顺带发布的一款硬件.这次更 ...

  5. 全球变脸应用新突破:实时秒变娃娃脸、全机型覆盖,断网也能用

    雷刚 发自 凹非寺  量子位 报道 | 公众号 QbitAI 秒变娃娃脸,技术应用又有新突破. 而且相比P图后"变脸",这次是拍摄短视频时终端实时进行"变脸", ...

  6. android动态图标主题,【官方秘籍】MAML动态图标百变插件完美适配全机型教程

    [官方秘籍]MAML动态图标&百变插件完美适配全机型教程 发布时间: 2016-01-27 11:29 一份manifest文件,可以同时运行在多个设备,只需要设置好在不同尺寸或密度的设备上使 ...

  7. android 卸载内置app,安卓全机型卸载预装软件

    安卓全机型卸载预装软件是一个可以在PC端使用的安卓手机工具,它的主要功能就是卸载各种手机内置预装软件,不管是华为.小米还是三星.魅族,安卓全机型卸载预装软件都可以为你一键搞定各种应用. 功能介绍 现在 ...

  8. msm android机型适配,小米系统MIUI10适配全机型了,高通机型通用适配,高通通刷包...

    原标题:小米系统MIUI10适配全机型了,高通机型通用适配,高通通刷包 今天给大家带来小米系统MIUI10,提供的是miui10稳定版高通通刷包,小米可以说是以系统开始发家的,系统流畅 功能 定制性在 ...

  9. Linux下网络流量实时监控工具 大全

    Linux下网络流量实时监控工具 大全 在工作中发现,经常因为业务的原因,需要即时了解某台服务器网卡的流量,虽然公司也部署了cacti软件,但cacti是五分钟统计的,没有即时性,并且 有时候打开监控 ...

最新文章

  1. 协同办公工具解决了什么问题?
  2. Linux系统安装Appach 2.4.6
  3. 浪潮云海OS C位出道,融合开放基础设施呼之欲出
  4. 解决MySQL Workbench导出低版本MySQL时报错Unknown table ‘column_statistics’ in information_schema的问题
  5. vs2015 下配置sfml
  6. 全志R311芯片规格书-datasheet资料分享
  7. python经济统计学论文_Python商务与经济统计学-1
  8. 嵌入式开发——用memtester软件进行内存压力测试
  9. 深入理解 Java 中的转义符: \u000a\u0022
  10. 记账软件分享,教你如何记账并管理所有账目
  11. 阿里物联网平台的使用
  12. sql数据库去重语法_oracle大数据去重sql语句
  13. OMV安装可道云kodexplorer网盘
  14. 登录SSH/winSCP一直显示密码错误
  15. Scale-Equalizing Pyramid Convolution for Object Detection论文阅读
  16. Android源码备用
  17. 不知道拍照识别文字的软件哪个好?这3款软件很实用
  18. 专插本 计算机基础与程序设计 2020届考生纯手敲 C语言与数据结构学习中遇到的所有问题都在这里了,建议直接三连
  19. paddlenlp调用ERNIE、使用ERNIEKIT
  20. ios开发聊天气泡实现

热门文章

  1. 多示例学习距离度量 (distance measures)和集合核 (set-kernel)
  2. cl.ez6.xyz index.php,[BJDCTF2020]EzPHP-POP链
  3. max3232ese_供销电子MAX3232ESE+T【全渠道分销系统】
  4. 激光打印机,保留打印记录的文档
  5. R语言 类别数据可视化(1)
  6. ffmpeg裁剪视频尺寸
  7. php账号登录验证手机号码,最完整的php验证手机号码
  8. Django 后台admin管理页面添加简易导出/下载数据功能的两种方法
  9. 《失控》摘录与读后感
  10. 机房管理系列(1) 联想保护系统EDU7.5在同传CMOS参数后奔溃的解决办法