欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android获取设备CPU核数、时钟频率以及内存大小的方法

程序员文章站 2024-03-05 07:58:54
本文实例讲述了android获取设备cpu核数、时钟频率以及内存大小的方法。分享给大家供大家参考,具体如下: 因项目需要,分析了一下 facebook 的开源项目 - d...

本文实例讲述了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程序设计有所帮助。