Android获取设备CPU核数、时钟频率以及内存大小的方法
本文实例讲述了android获取设备cpu核数、时钟频率以及内存大小的方法。分享给大家供大家参考,具体如下:
因项目需要,分析了一下 facebook 的开源项目 - device year class。
device year class 的主要功能是根据 cpu核数、时钟频率 以及 内存大小 对设备进行分级。代码很简单,只包含两个类:
deviceinfo -> 获取设备参数,
yearclass -> 根据参数进行分级。
下表是 facebook 公司提供的分级标准,其中 year 栏表示分级结果。
year | cores | clock | ram |
---|---|---|---|
2008 | 1 | 528mhz | 192mb |
2009 | n/a | 600mhz | 290mb |
2010 | n/a | 1.0ghz | 512mb |
2011 | 2 | 1.2ghz | 1gb |
2012 | 4 | 1.5ghz | 1.5gb |
2013 | n/a | 2.0ghz | 2gb |
2014 | n/a | >2ghz | >2gb |
关于输出年份的计算方法可以参考源码,本文只把一些比较常用的功能抽取出来做一个简要介绍。
获取 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() { @override public 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 -> khz if (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; } }
更多关于android相关内容感兴趣的读者可查看本站专题:《android视图view技巧总结》、《android操作xml数据技巧总结》、《android编程之activity操作技巧总结》、《android资源操作技巧汇总》、《android文件操作技巧汇总》、《android操作sqlite数据库技巧总结》、《android操作json格式数据技巧总结》、《android数据库操作技巧总结》、《android编程开发之sd卡操作方法汇总》、《android开发入门与进阶教程》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。