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

作者:feelang 时间:2022-09-13 07:09:32 

本文实例讲述了Android获取设备CPU核数、时钟频率以及内存大小的方法。分享给大家供大家参考,具体如下:

因项目需要,分析了一下 Facebook 的开源项目 - Device Year Class。

Device Year Class 的主要功能是根据 CPU核数、时钟频率 以及 内存大小 对设备进行分级。代码很简单,只包含两个类:

DeviceInfo -> 获取设备参数,
YearClass -> 根据参数进行分级。

下表是 Facebook 公司提供的分级标准,其中 Year 栏表示分级结果。

YearCoresClockRAM
20081528MHz192MB
2009n/a600MHz290MB
2010n/a1.0GHz512MB
201121.2GHz1GB
201241.5GHz1.5GB
2013n/a2.0GHz2GB
2014n/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,CPU,频率,内存
0
投稿

猜你喜欢

  • 基于idea 的 Java中的get/set方法之优雅的写法

    2023-11-26 20:22:50
  • Java优秀类库Hutool使用示例

    2021-12-09 18:12:06
  • 一篇文章带你玩转Spring bean的终极利器

    2022-08-20 10:47:33
  • Java实现多线程断点下载

    2022-04-27 00:29:16
  • 解决Android MediaRecorder录制视频过短问题

    2023-04-24 01:47:56
  • Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍

    2023-02-20 12:05:39
  • C#实现将一个字符串进行翻转显示的6种方法

    2022-05-07 22:55:10
  • Springboot整合多数据源代码示例详解

    2022-03-31 07:48:59
  • C#实现开机自动启动设置代码分享

    2021-10-08 20:45:14
  • Java中String、StringBuffer、StringBuilder的区别介绍

    2023-11-20 18:31:32
  • 在Kotlin开发中如何使用集合详解

    2022-03-06 02:22:30
  • C# 对MongoDB 进行增删改查的简单操作实例

    2022-03-07 14:10:26
  • Android 矢量室内地图开发实例

    2021-08-24 18:33:23
  • 基于TabLayout中的Tab间隔设置方法(实例讲解)

    2023-12-05 06:56:10
  • Springboot集成Spring Security实现JWT认证的步骤详解

    2021-09-18 13:18:08
  • Android标题栏中添加返回按钮功能

    2022-09-16 05:52:47
  • Spring Boot获取微信用户信息的超简单方法

    2023-04-19 19:47:23
  • Android EditText自定义样式的方法

    2021-10-06 22:37:37
  • Android实现屏幕旋转四个方向准确监听

    2022-06-07 08:57:32
  • Android中实现OkHttp上传文件到服务器并带进度

    2023-02-10 21:44:09
  • asp之家 软件编程 m.aspxhome.com