def systrace(self, *, app: str = None): """ 使用systrace """ app = self._get_app(app) systrace = self._config.get( 'systrace', '~/Library/Android/sdk/platform-tools/systrace/systrace.py') if not os.path.exists(os.path.expanduser(systrace)): print("no found systrace.py, please config using key: systrace") return print('wait for a while, generating systrace') out = f'{app}_systrace.html' try: sh(f"python2.7 {systrace} --app={app} --time=10 -o {out}") except Exception: print("need cmd python2.7 avaliable in path") return import webbrowser chrome = webbrowser.get('chrome') if chrome: chrome.open(f'file://{os.path.abspath(".")}/{out}') else: print(f'>>> 请使用chrome 打开 file://{os.path.abspath(".")}/{out}')
def dev_mem(self): """ 设备内存大小信息 """ print(sh("adb shell cat /proc/meminfo")) print("LOW MEM?", sh("adb shell getprop ro.config.low_ram").strip() or "false")
def dump_layout(self): """ 导出当前TOP Activity的布局 """ sh('adb shell uiautomator dump /sdcard/window_dump.xml; adb pull /sdcard/window_dump.xml' ) path = f'file://{os.path.abspath(".")}/window_dump.xml' open_with_webbrowser(path)
def screencap(self, file: str = "AndPerfScreencap.png"): """ 截图 Parameters: - file: 截图保存的file """ sh(f"adb shell screencap /sdcard/screencap.png; adb pull /sdcard/screencap.png {file}" ) open_with_webbrowser(f'file://{os.path.abspath(".")}/{file}')
def top_activity(self): """ 找出当前栈顶的页面 """ print() return sh( "adb shell dumpsys activity activities | grep ResumedActivity | tail -1 | awk '{print $4}'" )
def dump_thread(self, pid: int, tid: int) -> TaskInfo: try: infos = sh( f'adb shell cat /proc/{pid}/task/{tid}/stat 2>/dev/null').strip().split() name = infos[1] utime = int(infos[13]) stime = int(infos[14]) return TaskInfo(name, tid, utime, stime) except Exception as e: print(e)
def dump_process(self) -> ProcessInfo: start = time.time() data = sh(f"adb shell ps -ef 2>/dev/null").strip() for line in data.splitlines(): segs = line.strip().split() if segs[-1] == self.proc_name: pid = segs[1] if not pid: raise SystemExit(f'process: {self.proc_name} is not runing') tids = sh(f'adb shell ls /proc/{pid}/task 2>/dev/null').split() with ThreadPoolExecutor(20) as pool: dump_t = partial(self.dump_thread, pid) tasks = [task for task in pool.map(dump_t, tids) if task] utime, stime = sh( f'adb shell cat /proc/{pid}/stat 2>/dev/null').strip().split()[13:15] cost = time.time() - start print(f'dump process cost {cost:.2f}ms') return ProcessInfo(self.proc_name, pid, int(utime), int(stime), tasks)
def dump(app: str): pid = sh(f"adb shell ps -ef | grep -E '{app}$' | awk '{{print $2}}'") return Meminfo(sh(f'adb shell dumpsys meminfo {pid}'))
def dump(app: str): gfxinfo = sh(f"adb shell dumpsys gfxinfo {app}") return Gfxinfo(gfxinfo)
def reset(app: str): sh(f"adb shell dumpsys gfxinfo {app} reset 2>/dev/null")
def cpuinfo(self): """ 查看当前的cpu信息 """ print(sh("adb shell dumpsys cpuinfo"))
def dev_screen(self): """ 获取手机屏幕信息 """ print(sh("adb shell wm size")) print("density:", sh("adb shell getprop ro.sf.lcd_density"))