Android中如何获得系统相关的信息(比如CPU使用率,内存的总量和已用的量)
成都创新互联公司-专业网站定制、快速模板网站建设、高性价比开鲁网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式开鲁网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖开鲁地区。费用合理售后完善,10余年实体公司更值得信赖。
1、查看CPU
我想大家都很关系自己的爱机的CUP到底是什么具体信息呢.那就跟我来操纵吧.
打开超级终端,在命令行下输入SU回车,然后在#后输入cat /proc/cpuinfo回车.看到了吧.一串信息显示出来了.具体如下(以本人手机为例):
# cat cpuinfo
cat cpuinfo
Processor : ARMv6-compatible processor rev 2 (v6l)
BogoMIPS : 527.15
Features : swp half thumb fastmult edsp java
CPU implementer : 0x41
CPU architecture: 6TEJ
CPU variant : 0x1
CPU part : 0xb36
CPU revision : 2
Hardware : trout
Revision : 0080
Serial : 0000000000000000
里面的Processor 是处理器的意思.本人处理器是ARMv6兼容处理器
BogoMIPS(读作bogumips)是Linux操作系统中衡量计算机处理器运行速度的的一种尺度,而提供这种度量的程序也被称为BogoMips,是由Linux主要开发者linus Torvalds写的。
本人的是527.15
2、查看内存
内存查看可以从设置--存储卡和手机存储--里面会可以看到也可以下载高级任务管理器,方便你关闭程序和查询内存
3、通过查看文件获取设备信息
通过读取文件/proc/meminfo的信息获取Memory的总量。
ActivityManager. getMemoryInfo(ActivityManager.MemoryInfo)获取当前的可用Memory量。
通过读取文件/proc/cpuinfo系统CPU的类型等多种信息。
读取/proc/stat 所有CPU活动的信息来计算CPU使用率
命令中的"应用包名"应该替换为你需要查询的包名.
执行命令后, 在输出的内容中, 第二项即应用的进程名, 例如:
那么 22411 即为该应用当前的pid.
其中的"应用的pid"为上一步获取到的pid
执行命令后, 命令行工具即会打印应用运行信息
命令中的"应用包名"应该替换为你需要查询的包名.
命令执行后过段时间即会打印内存占用大小.
3)查看进程列表:adb shell "ps",同时也能获取到应用的UID,方式如下(不需root权限):
u0_a开头的都是Android的应用进程,Android的应用的UID是从10000开始,到19999结束,可以在Process.java中查看到(FIRST_APPLICATION_UID和LAST_APPLICATION_UID),u0_a后面的数字就是该应用的UID值减去FIRST_APPLICATION_UID所得的值,所以,对于截图这个应用进程,它是u0_a155,按前面的规制,它的UID就是155 + FIRST_APPLICATION_UID = 10155。
VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS = RSS = PSS = USS
使用 adb shell "dumpsys meminfo -s pakagename | pid"命令,输出结果分以下4部分:
PS:在apk内调用运行获取其他app的内存数据则需要root权限
adb命令:adb shell dumpsys gfxinfo package | pid
正常情况下帧率应该在16.67ms左右,1秒60帧,执行结果如下:
详细计算方法如下:
还有一个命令是: adb shell dumpsys SurfaceFlinger --latency LayerName
其中LayerName在各个不同系统中获取的命令是不一样的
在Android 6系统直接就是SurfaceView
在Android 7系统中可以通过 dumpsys window windows | grep mSurface | grep SurfaceView 然后通过数据截取到
在Android 8系统中可以通过 dumpsys SurfaceFlinger | grep android包名获取到
执行命令结果如下:
计算方法比较简单,一般打印出来的数据是129行(部分机型打印两次257行,但是第一部分是无效数据,取后半部分),取len-2的第一列数据为end_time,取len-128的第一列数据为start_time
fps = 127/((end_time - start_time) / 1000000.0)
至于为啥要取第一列数据,这里不做过多介绍,欢迎参看这两篇文章
老罗的文章SurfaceView原理
Android性能测试之fps获取
至于为啥要处于1000000,因为命令打印出来的是纳秒单位,要转为毫秒进行计算,127就是因为命令一次打印出来127帧的数据而已
有两种方法可以获取
1) adb shell "top -n 5 | grep package | pid" ,第三列就是实时监控的CPU占用率(-n 指定执行次数,不需root权限),这边top命令执行需要2到3s左右,一般可以采用busybox 的top命令执行,效率会快很多
2) adb shell "dumpsys cpuinfo | grep package | pid"
两种方法直接区别在于,top是持续监控状态,而dumpsys cpuinfo获取的实时CPU占用率数据
adb命令:adb shell "dumpsys batterystats package | pid" (Android 5.0后引入)
获取单个应用的耗电量信息,具体返回结果待研究
adb命令:adb shell "dumpsys battery"
出现信息解读:
AC powered:false 是否连接AC(电源)充电线
USB powered:true 是否连接USB(PC或笔记本USB插口)充电
Wireless powered:false 是否使用了无线电源
status: 1 电池状态,2为充电状态,其他为非充电状态
level:58 电量(%)
scale: 100. 电量最大数值
voltage: 3977 当前电压(mV)
current now: -335232. 当前电流(mA)
temperature:355 电池温度,单位为0.1摄氏度
adb 命令:adb shell "dumpsys package | pid | grep UID" [通过ps命令,获取app的UID(安装后唯一且固定)]
adb shell cat /proc/uid_stat/UID/tcp_rcv [cat为查看命令,读取tcp_rcv获取应用接收流量信息(设备重启后清零)]
adb shell cat /proc/uid_stat/UID/tcp_snd [cat为查看命令,读取tcp_snd获取应用发送流量信息(设备重启后清零)]
计算流量消耗步骤:
或者还有一种方式获取应用流量消耗:
首先判断类型:
cat /sys/class/thermal/thermal_zone*/type
只有红框框出来的是有效的
cat /sys/class/thermal/thermal_zone*/temp
获取CPU温度
dumpsys battery | grep temperature 单位0.1摄氏度
获取/proc/stat文件内容(无权限限制)
总的cpu时间片是 total = user+nice+system+idle+iowait+irq+softirq
忙碌时间为 notidle = user+nice+system +iowait+irq+softirq
cpu使用率计算方法为,先取开始的total值和忙碌时间notidle,隔一段时间片,再取一次计算total2,notidle2, cpuuse = (notidle2 – notidle) * 100 / (total2 - total)%
PS:由于Android 8权限收紧,在Android 8系统手机内apk内读取文件内容为空,需要shell权限才可获取文件内容,下同
读/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq文件的值,X不定,看是几核手机,scaling_cur_freq是否存在也不一定,需要判断
至于为啥不取cpuinfo_cur_freq文件的值,原因是android 6,7系统获取的时候,这个文件shell没有读取权限,需要root权限
参考文章:
Android 6,7系统可执行
dumpsys window windows | grep "mCurrentFocus"
执行结果一般为类似:
mCurrentFocus=Window{81caaa5 u0 com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity}
按照一定规则把com.tencent.mobileqq提取出来即可
直接apk内读取文件即可,不需要shell权限(支持到Android8)
Gpu使用率获取:会得到两个值,(前一个/后一个)*100%=使用率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpubusy
Gpu工作频率:
adb shell cat /sys/class/kgsl/kgsl-3d0/gpuclk
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq
Gpu最大、最小工作频率:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/min_freq
Gpu可用频率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies
Gpu可用工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_governors
Gpu当前工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/governor
直接按DEL+CTRL+ALT键,调出电脑任务管理器,查看性能,就可以看到有CPU占用率,核心数占用率的显示。
或者安装常见的鲁大师软件,在温度栏下,也可以直接看到CPU的占用率。
获取 CPU 核数 Linux 中的设备都是以文件的形式存在,CPU 也不例外,因此 CPU 的文件个数就等价与核数。 Android 的 CPU 设备文件位于/sys/devices/system/cpu/目录,文件名的的格式为cpu\d+。 root@generic_x86_64:/sys/devices/system/cpu # ls cpu0 cpufreq cpuidle kernel_max modalias offline online possible power present uevent统计一下文件个数便可以获得 CPU 核数。 public static int getNumberOfCPUCores() {if (Build.VERSION.SDK_INT = Build.VERSION_CODES.GINGERBREAD_MR1) {// Gingerbread doesn't support giving a single application access to both cores, but a// handful of devices (Atrix 4G and Droid X2 for example) were released with a dual-core// chipset and Gingerbread; that can let an app in the background run without impacting// the foreground application. But for our purposes, it makes them single core.return 1;}int cores;try {cores = new File("/sys/devices/system/cpu/").listFiles(CPU_FILTER).length;} catch (SecurityException e) {cores = DEVICEINFO_UNKNOWN;} catch (NullPointerException e) {cores = DEVICEINFO_UNKNOWN;}return cores; }private static final FileFilter CPU_FILTER = new FileFilter() {@Overridepublic boolean accept(File pathname) {String path = pathname.getName();//regex is slow, so checking char by char.if (path.startsWith("cpu")) {for (int i = 3; i path.length(); i++) {if (path.charAt(i) '0' path.charAt(i) '9') {return false;}}return true;}return false;} };获取时钟频率 获取时钟频率需要读取系统文件 -/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq或者/proc/cpuinfo。Android 模拟器中并没有cpuinfo_max_freq文件,因此只能读取/proc/cpuinfo。 /proc/cpuinfo包含了很多 cpu 数据。 processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 70 model name : Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz stepping : 1 cpu MHz : 0.000 cache size : 1024 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 4 wp : yes代码如下: public static int getCPUMaxFreqKHz() {int maxFreq = DEVICEINFO_UNKNOWN;try {for (int i = 0; i getNumberOfCPUCores(); i++) {String filename ="/sys/devices/system/cpu/cpu" + i + "/cpufreq/cpuinfo_max_freq";File cpuInfoMaxFreqFile = new File(filename);if (cpuInfoMaxFreqFile.exists()) {byte[] buffer = new byte[128];FileInputStream stream = new FileInputStream(cpuInfoMaxFreqFile);try {stream.read(buffer);int endIndex = 0;//Trim the first number out of the byte buffer.while (buffer[endIndex] = '0' buffer[endIndex] = '9' endIndex buffer.length) endIndex++;String str = new String(buffer, 0, endIndex);Integer freqBound = Integer.parseInt(str);if (freqBound maxFreq) maxFreq = freqBound;} catch (NumberFormatException e) {//Fall through and use /proc/cpuinfo.} finally {stream.close();}}}if (maxFreq == DEVICEINFO_UNKNOWN) {FileInputStream stream = new FileInputStream("/proc/cpuinfo");try {int freqBound = parseFileForValue("cpu MHz", stream);freqBound *= 1000; //MHz - kHzif (freqBound maxFreq) maxFreq = freqBound;} finally {stream.close();}}} catch (IOException e) {maxFreq = DEVICEINFO_UNKNOWN; //Fall through and return unknown.}return maxFreq; }获取内存大小 如果 SDK 版本大于等于JELLY_BEAN,可以通过ActivityManager来获取内从大小。 ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo(); ActivityManager am = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE); am.getMemoryInfo(memInfo);如果版本低于JELLY_BEAN,则只能读取系统文件了。 FileInputStream stream = new FileInputStream("/proc/meminfo"); totalMem = parseFileForValue("MemTotal", stream);完整代码如下: @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static long getTotalMemory(Context c) {// memInfo.totalMem not supported in pre-Jelly Bean APIs.if (Build.VERSION.SDK_INT = Build.VERSION_CODES.JELLY_BEAN) {ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();ActivityManager am = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);am.getMemoryInfo(memInfo);if (memInfo != null) {return memInfo.totalMem;} else {return DEVICEINFO_UNKNOWN;}} else {long totalMem = DEVICEINFO_UNKNOWN;try {FileInputStream stream = new FileInputStream("/proc/meminfo");try {totalMem = parseFileForValue("MemTotal", stream);totalMem *= 1024;} finally {stream.close();}} catch (IOException e) {}return totalMem;} }