uiautomator多次写入文件报错

本文介绍了一个在使用UIAutomator2进行测试时遇到的问题:多次写入文件时出现System.err错误。通过检查代码发现是因为FileOutputStream对象未正确置空导致。文中提供了修复该问题的具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用uiautomator2.0进行测试,将结果写入文件,第2次以后写入报错:System.err,但是没有具体的错误信息。

后来发现是关闭之后没有将FileOutputStream对象置null导致。

public void writeResult(String path,ArrayList<String> arrayList){
        path = "sdcard/test/"+path+".txt";
        try {
            if(bw==null)
            bw = new FileOutputStream(path,false);
            for(String text : arrayList){
                Log.d(TAG, "writeResult: text=" + text);
                bw.write(text.getBytes());
                bw.flush();
                bw.write("\n".getBytes());
                bw.flush();
            }
            //因为关闭了没有置为null所以下次调用时出错
            bw.close();
            bw = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

import uiautomator2 as u2 import time import re import logging import threading from adbutils import adb import csv # 配置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') cpu_data = [] # 存储CPU数据的列表 # 浏览器包名列表 BROWSER_PACKAGES = [ 'com.android.chrome','com.google.android.apps.messaging' ] class CPUMonitor: def __init__(self, device): self.device = device self.prev_total = None self.prev_idle = None self.prev_pid_stats = {} def get_system_cpu_usage(self): """获取系统级CPU使用率(基于/proc/stat)""" try: # 读取/proc/stat获取整机CPU数据 output = self.device.shell("cat /proc/stat | grep '^cpu '") parts = output.output.split() values = [int(x) for x in parts[1:8]] # 取前7个字段 # 计算总时间和空闲时间 total_time = sum(values) idle_time = values[3] + values[4] # idle + iowait # 首次采样无比较基准 if self.prev_total is None or self.prev_idle is None: self.prev_total = total_time self.prev_idle = idle_time time.sleep(1) return self.get_system_cpu_usage() # 计算增量 total_delta = total_time - self.prev_total idle_delta = idle_time - self.prev_idle # 更新历史值 self.prev_total = total_time self.prev_idle = idle_time # 计算使用率 if total_delta == 0: return 0.0 return 100.0 * (total_delta - idle_delta) / total_delta except Exception as e: logging.error(f"获取系统CPU失败: {str(e)}") return 0.0 def get_process_cpu_usage(self, package_name): """获取指定包名的进程级CPU使用率""" try: # 获取所有相关PID pids = self._get_package_pids(package_name) if not pids: return 0.0 # 获取当前进程统计 current_stats = {} for pid in pids: stat = self._get_pid_stat(pid) if stat: current_stats[pid] = stat # 首次采样 if not self.prev_pid_stats.get(package_name): self.prev_pid_stats[package_name] = current_stats time.sleep(1) return self.get_process_cpu_usage(package_name) # 计算增量 prev_stats = self.prev_pid_stats[package_name] total_delta = 0 valid_pids = 0 for pid, curr in current_stats.items(): if pid in prev_stats: prev = prev_stats[pid] # 计算进程CPU时间增量 (utime + stime) process_delta = (curr['utime'] + curr['stime']) - \ (prev['utime'] + prev['stime']) total_delta += process_delta valid_pids += 1 # 更新历史数据 self.prev_pid_stats[package_name] = current_stats # 获取系统级CPU时间增量 system_output = self.device.shell("cat /proc/stat | grep '^cpu '").output system_parts = system_output.split() system_values = [int(x) for x in system_parts[1:8]] system_total = sum(system_values) if self.prev_total is None: self.prev_total = system_total return 0.0 system_delta = system_total - self.prev_total # 计算使用率百分比 if system_delta > 0 and valid_pids > 0: return 100.0 * total_delta / system_delta return 0.0 except Exception as e: logging.error(f"获取进程CPU失败[{package_name}]: {str(e)}") return 0.0 def _get_package_pids(self, package_name): """获取包名的所有进程ID""" try: output = self.device.shell(f"pgrep -f {package_name}").output return [pid.strip() for pid in output.splitlines() if pid.strip()] except: return [] def _get_pid_stat(self, pid): """获取指定PID的/proc/stat数据""" try: output = self.device.shell(f"cat /proc/{pid}/stat").output parts = output.split() # 解析关键字段 (utime=14, stime=15 从1开始计数) return { 'utime': int(parts[13]), 'stime': int(parts[14]) } except: return None # def reduce_cpu_load(device): # """降低设备CPU负载的优化方案""" # try: # # 更彻底的进程清理 # device.shell("am kill-all") # # 限制后台进程 # device.shell("settings put global background_process_limit 3") # # 清除缓存 # device.shell("sync && echo 3 > /proc/sys/vm/drop_caches") # logging.info("已执行深度CPU降载操作") # except Exception as e: # logging.error(f"降载操作出错: {str(e)}") def log_cpu_data(sys_cpu,proc_cpu): """记录并保存CPU数据""" timestamp = time.strftime("%Y-%m-%d %H:%M:%S") log_msg = f"System CPU: {sys_cpu:.2f}%, Process CPU: {proc_cpu:.2f}%" logging.info(log_msg) # 添加到内存列表 cpu_data.append([timestamp, sys_cpu, proc_cpu]) # 实时写入CSV(每次记录都保存) with open('cpu_usage.csv', 'a', newline='') as f: writer = csv.writer(f) writer.writerow([timestamp, sys_cpu, proc_cpu]) def monitor_device(device_serial, max_cpu=80.0): """监控单个设备的CPU使用率(高精度版)""" try: device = u2.connect(device_serial) monitor = CPUMonitor(device) logging.info(f"开始高精度监控设备: {device_serial}") while True: try: # 获取系统级CPU使用率 total_cpu = monitor.get_system_cpu_usage() logging.info(f"整机CPU使用率: {total_cpu:.2f}%") # # 获取浏览器总CPU使用率 # browser_cpu = 0.0 # browser_details = {} apk_details = {} for package in BROWSER_PACKAGES: cpu_val = monitor.get_process_cpu_usage(package) # browser_details[package] = cpu_val # browser_cpu += cpu_val apk_details[package] = cpu_val logging.info(f"{package}详情: {cpu_val:.2f}%") logging.info("详情: " + ", ".join([f"{pkg}: {val:.2f}%" for pkg, val in apk_details.items()])) time.sleep(0.5) log_cpu_data(apk_details.items()) # logging.info("浏览器CPU详情: " + # ", ".join([f"{pkg}: {val:.2f}%" for pkg, val in browser_details.items()])) # logging.info(f"浏览器总CPU使用率: {browser_cpu:.2f}%") # # 监控逻辑 # if total_cpu > max_cpu and browser_cpu > total_cpu * 0.4: # logging.warning(f"设备 {device_serial} CPU超过阈值({max_cpu}%),浏览器占用过高,执行降负载操作") # reduce_cpu_load(device) time.sleep(5) except Exception as e: logging.error(f"监控循环出错: {str(e)}") time.sleep(10) except Exception as e: logging.error(f"设备连接失败: {device_serial}, 错误: {str(e)}") def main(): """主函数:监控所有连接的Android设备""" devices = [d.serial for d in adb.device_list()] if not devices: logging.warning("未找到连接的Android设备") return logging.info(f"找到 {len(devices)} 台设备: {', '.join(devices)}") for device_serial in devices: thread = threading.Thread(target=monitor_device, args=(device_serial,)) thread.daemon = True thread.start() # 保持主线程运行 while True: time.sleep(1) if __name__ == "__main__": try: main() except KeyboardInterrupt: logging.info("\n监控已停止") 报错:监控循环出错: log_cpu_data() missing 1 required positional argument: 'proc_cpu'
最新发布
07-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值