Python获取android设备cpu和内存占用情况

(编辑:jimmy 日期: 2024/12/31 浏览:2)

功能:获取android设备中某一个app的cpu和内存

环境:python和adb

使用方法:使用adb连接android设备,打开将要测试的app,执行cpu/内存代码

cpu获取代码如下:(输入参数为脚本执行时间)

# coding:utf-8
'''
获取系统total cpu
'''
import os, csv
import time
import csv
import numpy as np
from matplotlib import pyplot as plt

cpu_list = []
time_list = []
app_list = []
lines = []
package_name = []


# 读取进程名称(包名)
def get_applist():
  global package_name
  with open('config/director.txt', encoding='utf-8', mode='r') as f:
    lines_all = f.readlines()
    for appname in lines_all:
      package_name1 = appname
      appname_new = appname[0:15]
      package_name.append(package_name1)
      lines.append(appname_new)
    for line in lines:
      app_list.append(line.strip())


# 获取cpu数值
def get_cpu():
  global filename
  with open(filename, encoding="utf-8", mode="r") as f:
    lines = f.readlines()
    for appname in app_list:
      for lis in lines:
        # 适配低版本手机
        if appname in lis and '%' in lis:
          now = time.strftime("%H:%M:%S", time.localtime())
          time_list.append(now)
          cpu_1 = lis.split('%')[0]
          cpu_2 = cpu_1.split(' ')
          # print(cpu_2)
          cpu = cpu_2[len(cpu_2) - 1]
          print(cpu, now)
          cpu_list.append(cpu)
          break
        # 适配高版本手机
        elif appname in lis:
          now = time.strftime("%H:%M:%S", time.localtime())
          time_list.append(now)
          cpu1 = lis.split(' ')
          # print(cpu1)
          cpu2 = list(set(cpu1))
          cpu2.sort(key=cpu1.index)
          cpu_h = cpu2[len(cpu2) - 4]
          print(cpu_h, now)
          cpu_list.append(cpu_h)
          break
        else:
          pass


# csv头部
def write_head():
  headers = ['name:']
  headers.append(app_list[0])
  headers.append('init_cpu')
  with open('log_su/cpuinfo.csv', 'w+', newline='') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=headers)
    writer.writeheader()


# 将数值写入csv,用于绘图时读取
def write_report():
  # headers = ['name', 'aaa', 'init_cpu']
  with open('log_su/cpuinfo.csv', 'a+', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for key in cpu_list:
      writer.writerow([' ', ' ', key])


# 绘制折线图,生成测试报告
def mapping():
  filename = 'log_su/cpuinfo.csv'
  with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    highs = []
    for row in reader:
      high = row[2]
      highs.append(high)
    # print(highs)

  wights = time_list
  highs_float = list(map(float, highs))
  # print(f"****{highs}")
  print(f"CPU值:{highs_float}")
  # 输出平均值
  total = 0
  for value in highs_float:
    total += value
  average = round(total/len(highs_float), 2)
  print(f"CPU平均值:{average}")

  #输出最低值和最高值
  highs_hl = sorted(highs_float)
  print(f"CPU最低值:{highs_hl[0]}")
  print(f"CPU最高值:{highs_hl[len(highs_hl)-1]}")

  # 根据数据绘制图形
  plt.figure(figsize=(11, 4), dpi=600)
  # 生成网格
  # plt.grid()
  plt.grid(axis="y")
  # 折线图
  if package_name[0] == 'com.oneapp.max.security.pro.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="PPP")
  elif package_name[0] == 'com.oneapp.max.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Opt1.6.1")
  elif package_name[0] == 'com.boost.clean.coin.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Fastclear")
  elif package_name[0] == 'com.walk.sports.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Walk")
  elif package_name[0] == 'com.diamond.coin.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Amber")
  elif package_name[0] == 'com.oneapp.max.cleaner.booster.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Space")
  else:
    plt.plot(wights, highs_float, "c-", linewidth=1, label=package_name[0])
  # 坐标轴范围
  # plt.ylim(300, 400)
  # plt.xlim(0, 10)

  plt.xlabel('time(H:Min:S)', fontsize=16)
  plt.ylabel("cpu_realtime(%)", fontsize=16)
  plt.title("cpu real time line chart", fontsize=24)
  plt.legend()

  # 横坐标显示间隔
  if len(wights) <= 15:
    pass
  else:
    t = int(len(wights) / 15)
    plt.xticks(range(0, len(wights), t))

  # 纵坐标显示间隔
  # plt.yticks(range(100, 300, 10))

  # 旋转日期
  plt.gcf().autofmt_xdate()

  # 展示每个坐标
  # for a, b in zip(wights, highs_float):
  #   plt.text(a, b, (a, b), ha='center', va='bottom', fontsize=8)

  # plt.show()

  time_now = time.strftime("%m%d-%H:%M:%S", time.localtime())
  path = "report/" + time_now
  plt.savefig(path)


# 自动识别当前需检测的
def name_app():
  cmd = 'adb shell dumpsys window | grep mCurrentFocus > log_su/name_info.csv'
  os.system(cmd)
  with open('log_su/name_info.csv', encoding='utf-8', mode='r') as f:
    lines = f.readlines()
    for line in lines:
      if 'mCurrentFocus' in line:
        name1 = line.split('/')[0].split(' ')
        name = name1[len(name1) - 1]

  with open('config/director.txt', encoding='utf-8', mode='w') as f_name:
    text = name
    f_name.write(text)
  print(f"将要监测的包名为:{text}")

#控制监测时间
def time_control():
  global filename
  while True:
    end_time = time.time()
    if (end_time - start_time)/60 >= tol_time:  #分钟
    # if end_time - start_time >= tol_time: # 秒
      break

    time.sleep(1)
    adb = "adb shell top -n 1 > log_su/adb_info.csv"
    d = os.system(adb)
    filename = "log_su/adb_info.csv"
    get_cpu()


if __name__ == "__main__":
  name_app()
  tol_time = int(input("请输入脚本执行时间(分钟):"))
  start_time = time.time()
  get_applist()
  write_head()
  time_control()
  write_report()
  mapping()

会在.py文件同级目录下生成3个文件夹,config、log_su、report,其中运行结果在report中

结果以是生成折线图,看起来直观,如下:

Python获取android设备cpu和内存占用情况

这里我解释下,cpu占比是adb获取的实时占比,但是满值并不一定是100%,比如这张图,用的是一个八核的手机,所以CPU满值是800%

内存获取代码如下:(输入参数为脚本执行时间)

# coding:utf-8
'''
获取系统total memory
'''
import os, csv
import time
import csv
import numpy as np
from matplotlib import pyplot as plt

mem_dict = {}
time_list = []
app_list = []
package_name = []
t = 0
def get_applist():
  global package_name
  with open('config/director.txt', encoding='utf-8', mode='r') as f:
    lines = f.readlines()
    for line in lines:
      package_name1 = line
      package_name.append(package_name1)
      app_list.append(line.strip())


def get_mem():
  global filename
  with open(filename, encoding="utf-8", mode="r") as f:
    lines = f.readlines()
    start_flag = False
    for appname in app_list:
      for line in lines:
        if "Total PSS by OOM adjustment" in line:
          break
        if appname in line and 'pid' in line and 'kB' in line:
          mem_v = line.strip().split(':')[0].replace('kB', '').replace(',', '')
          line_name = line.split(':')[1].split('(')[0].strip()
          if line_name in appname:
            mem_v = round(float(mem_v) / 1024, 2)
            mem_dict[appname] = mem_v
            now_v = time.strftime("%H:%M:%S", time.localtime())
            # now_int = int(now_v)
            time_list.append(now_v)
            print(mem_v, now_v)
            break
        elif appname in line and 'pid' in line and 'K' in line:
          mem_v = line.strip().split(':')[0].replace('K', '').replace(',', '')
          line_name = line.split(':')[1].split('(')[0].strip()
          if line_name in appname:
            mem_v = round(float(mem_v) / 1024, 2)
            mem_dict[appname] = mem_v
            now_v = time.strftime("%H:%M:%S", time.localtime())
            # now_int = int(now_v)
            time_list.append(now_v)
            print(mem_v, now_v)
            break

def write_head():
  headers = ['name:']
  headers.append(app_list[0])
  headers.append('init_mem')
  with open('log_su/meminfo.csv', 'w+', newline='') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=headers)
    writer.writeheader()

def write_report():
  headers = ['name','aaa', 'init_mem']
  with open('log_su/meminfo.csv', 'a+', newline='') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=headers)
    for key in mem_dict:
      writer.writerow({'init_mem': mem_dict[key]})


def mapping():
  filename = 'log_su/meminfo.csv'
  with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    highs = []
    for row in reader:
      high = row[2]
      highs.append(high)
    # print(highs)

  wights = time_list
  highs_float = list(map(float, highs))

  print(f"内存值:{highs_float}")

  # 输出平均值
  total = 0
  for value in highs_float:
    total += value
  average = round(total / len(highs_float), 2)
  print(f"内存平均值:{average}")

  # 输出最低值和最高值
  highs_hl = sorted(highs_float)
  print(f"内存最低值:{highs_hl[0]}")
  print(f"内存最高值:{highs_hl[len(highs_hl) - 1]}")

  # 根据数据绘制图形

  plt.figure(figsize=(11, 4), dpi=600)

  # 生成网格
  # plt.grid()
  plt.grid(axis="y")

  if package_name[0] == 'com.oneapp.max.security.pro.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="PPP")
  elif package_name[0] == 'com.oneapp.max.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Opt")
  elif package_name[0] == 'com.boost.clean.coin.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="fastclear")
  elif package_name[0] == 'com.walk.sports.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Walk")
  elif package_name[0] == 'com.diamond.coin.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Amber")
  elif package_name[0] == 'com.oneapp.max.cleaner.booster.cn':
    plt.plot(wights, highs_float, "c-", linewidth=1, label="Space")
  else:
    plt.plot(wights, highs_float, "c-", linewidth=1, label=package_name[0])
  # 坐标轴范围
  # plt.ylim(300, 400)
  # plt.xlim(0, 10)

  plt.xlabel('time(H:Min:S)', fontsize=16)
  plt.ylabel("Number (Mb)", fontsize=16)
  plt.title("meminfo", fontsize=24)
  plt.legend()

  # 横坐标显示间隔
  if len(wights) <= 15:
    pass
  else:
    t = int(len(wights) / 15)
    plt.xticks(range(0, len(wights), t))

  # 坐标刻度
  # my_y_ticks = np.arange(300, 400, 10)
  # my_x_ticks = np.arange(1, 10, 1)
  # plt.xticks(my_x_ticks)
  # plt.yticks(my_y_ticks)
  # plt.yticks(range(100, 300, 10))

  #旋转日期
  plt.gcf().autofmt_xdate()

  # 展示每个坐标
  # for a, b in zip(wights, highs_float):
  #   plt.text(a, b, (a, b), ha='center', va='bottom', fontsize=8)

  # plt.show()

  time_now = time.strftime("%m%d-%H:%M:%S", time.localtime())
  path = "report/" + time_now
  plt.savefig(path)

def name_app():
  cmd = 'adb shell dumpsys window | grep mCurrentFocus > log_su/name_info.csv'
  os.system(cmd)
  with open('log_su/name_info.csv', encoding='utf-8', mode='r') as f:
    lines = f.readlines()
    for line in lines:
      if 'mCurrentFocus' in line:
        name1 = line.split('/')[0].split(' ')
        name = name1[len(name1) - 1]

  with open('config/director.txt', encoding='utf-8', mode='w') as f_name:
    text = name
    f_name.write(text)
  print(f"将要监测的包名为:{text}")

def time_control():
  global filename
  while True:
    end_time = time.time()
    if (end_time - start_time)/60 >= tol_time:  #分钟
    # if end_time - start_time >= tol_time:  #秒
      break
    # time.sleep(2)
    # filename = str(input("请输入文件名:"))
    adb = "adb shell dumpsys meminfo > log_su/adb_info.csv"
    d = os.system(adb)
    filename = "log_su/adb_info.csv"
    get_mem()
    write_report()

if __name__ == "__main__":
  name_app()
  tol_time = int(input("请输入脚本执行时间(分钟):"))
  start_time = time.time()
  get_applist()
  write_head()
  time_control()
  mapping()

会在.py文件同级目录下生成3个文件夹,config、log_su、report,其中运行结果在report中

生成的内存结果图如下:

Python获取android设备cpu和内存占用情况

一句话新闻

一文看懂荣耀MagicBook Pro 16
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?