#python #安卓 如果要通过python的形式,检测安卓的cpu占用率,是需要通过adb调试的形式,一般是连线安卓实体机; 在执行上述操作之前,需要确认的是,安卓的adb调试,是已经配置完成和可用的,参考[[设置adb环境变量]],还有python 3的环境变量,也是需要的,可参考[[python设置环境变量]],配置完成: ![[Pasted image 20250411151801.png]] 其中,安卓的bundleid包名,是`com.DefaultCompany.LGCollecter` ![[Pasted image 20250411152113.png]] 这是考虑了cpu多核情况的python脚本,1秒的时间间隔,采集cpu时间,可以直接执行: ## cpu.py ``` py import subprocess import time PACKAGE = "com.DefaultCompany.LGCollecter" INTERVAL = 1.0 def get_cpu_cores(): """获取CPU核心数""" try: output = subprocess.check_output( "adb shell grep -c processor /proc/cpuinfo", stderr=subprocess.STDOUT, shell=True ) return int(output.strip()) except: return 1 def get_pid(): """持续获取进程ID""" while True: try: output = subprocess.check_output( f"adb shell pidof {PACKAGE}", stderr=subprocess.STDOUT, shell=True ) pid = output.decode().strip() if pid: return int(pid) except subprocess.CalledProcessError: pass print("等待应用启动...") time.sleep(2) def read_proc_stat(): """读取系统CPU总时间""" output = subprocess.check_output( "adb shell head -n1 /proc/stat", stderr=subprocess.STDOUT, shell=True ).decode() parts = output.strip().split()[1:8] return sum(map(int, parts)) def read_process_cpu(pid): """读取进程CPU时间""" output = subprocess.check_output( f"adb shell cat /proc/{pid}/stat", stderr=subprocess.STDOUT, shell=True ).decode() parts = output.strip().split() utime = int(parts[13]) stime = int(parts[14]) return utime + stime def main(): cores = get_cpu_cores() pid = get_pid() print(f"监控开始 (PID: {pid}, CPU核心: {cores})") prev_proc_time = read_process_cpu(pid) prev_total_time = read_proc_stat() while True: time.sleep(INTERVAL) curr_proc_time = read_process_cpu(pid) curr_total_time = read_proc_stat() proc_diff = curr_proc_time - prev_proc_time total_diff = curr_total_time - prev_total_time if total_diff == 0: usage = 0.0 else: # 计算实际CPU使用率(考虑多核) usage = 100.0 * proc_diff / total_diff # 转换为多核百分比(可选) # usage = usage * 100.0 / cores print(f"{time.strftime('%H:%M:%S')} CPU使用率: {usage:.1f}%") prev_proc_time = curr_proc_time prev_total_time = curr_total_time if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n监控已停止") except Exception as e: print(f"发生错误: {str(e)}") ``` 安卓相关的,java逻辑,也可以实现,cpu占用率的测算,但是这个不是非常准确,另外安卓相关的,如果要获取,系统总的cpu频率等数据相关,也就是`/proc/stat`系统级别的信息,一般是不开放这个接口权限的,所以不够adb方式的,python脚本获取的数据准确; 需先申请权限,参考一下,权限申请: ## AndroidManifest.xml ``` xml ``` ## Sys.java ``` java public static float getProcessCPUUsageOnce() { try { // 第一次采样 BufferedReader br1 = new BufferedReader(new FileReader("/proc/self/stat")); String line1 = br1.readLine(); String[] parts1 = line1.split("\\s+"); long utime1 = Long.parseLong(parts1[13]); long stime1 = Long.parseLong(parts1[14]); long cpuTime1 = utime1 + stime1; // 等待1秒 Thread.sleep(1000); // 第二次采样 BufferedReader br2 = new BufferedReader(new FileReader("/proc/self/stat")); String line2 = br2.readLine(); String[] parts2 = line2.split("\\s+"); long utime2 = Long.parseLong(parts2[13]); long stime2 = Long.parseLong(parts2[14]); long cpuTime2 = utime2 + stime2; // 计算使用率 int hz = getSystemClockTicks(); float usage = ((cpuTime2 - cpuTime1) / (float) hz) * 100f; // 新增日志输出 Log.d("CPUUsage", "系统CPU使用率: " + String.format("%.2f", usage) + "%"); return Math.max(0, Math.min(usage, 100)); } catch (Exception e) { Log.e("CPUUsage", "获取CPU使用率失败", e); e.printStackTrace(); } return -1f; } // 新增帮助方法 获取CPU时钟频率Hz private static int getSystemClockTicks() { try { // 方法1:通过系统属性获取(需要API 21+) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { int hz = (int) android.system.Os.sysconf(android.system.OsConstants._SC_CLK_TCK); if (hz > 0) { return hz; } } // 方法2:通过/proc文件系统动态计算 // 读取进程启动时间和系统运行时间 BufferedReader statBr = new BufferedReader(new FileReader("/proc/self/stat")); String[] stat = statBr.readLine().split("\\s+"); long startTime = Long.parseLong(stat[21]); // 启动时间(jiffies) long utime = Long.parseLong(stat[13]); // 用户态时间 BufferedReader uptimeBr = new BufferedReader(new FileReader("/proc/uptime")); String uptimeStr = uptimeBr.readLine().split("\\s+")[0]; float uptime = Float.parseFloat(uptimeStr); // 系统运行时间(秒) // 计算HZ:startTime的单位是jiffies,uptime的单位是秒 // HZ = startTime / (uptime - (process_start_time_seconds)) long processStartSeconds = startTime / 100; // 假设初始HZ=100进行估算 float actualHz = startTime / (uptime - processStartSeconds); // 取整并限制合理范围 int hz = Math.max(100, Math.min(1000, (int)actualHz)); Log.d("ClockTicks", "Calculated HZ: " + hz); return hz; } catch (Exception e) { Log.e("ClockTicks", "Error calculating HZ, using default 100", e); return 100; // 保底返回值 } } ```