用 adb 监控安卓手机前台 App、后台进程,用于保活、杀后台分析

本贴最后更新于 698 天前,其中的信息可能已经沧海桑田

刷到了 ,他们每次检测手机后台应用存活,都是个体力活,要一轮又一轮启动应用,再次启动来检测是否存活。

我觉得他们花的一些力气,以手工思维做,投入产出比太低,有很大的改进空间。检测应用状态,应当以程序思维做事。

对于智能手机,应该是有更简单的方法获得各个应用的状态的。安卓手机可以使用 adb 执行 shell 代码,获得系统状态。

但是苹果,权限太封闭,暂时没办法用代码收集系统状态(或许开发者、越狱可以?)

要在以前,我肯定弄不了,查文档就要累死我。但现在有了 ChatGPT 了,许多细节的小问题问它就能解决了。

动态监控前台 App

首先,是要得到手机的前台 App,可以在 adb shell 中用这条命令:

dumpsys window displays | grep mFocusedApp

得到这样的输出:

mFocusedApp=ActivityRecord{3223fe1 u0 com.android.browser/.BrowserActivity t24131}

也就是目前的前台应用是浏览器,进程 id 为 24131。如果要持续监听写入到文件,就可以用:

while true; do echo "$(date) $(dumpsys window displays | grep mFocusedApp)" >> /sdcard/fg_log.txt; sleep 1; done

动态监控所有 App 进程

其次,就是要得到后台进程的信息,用到了 top 命令。

top 的输出中,不同的应用程序进程具有不同的用户标识(USER)。在 Android 系统中,用户标识通常以 u0_aXXX 的形式表示,每个应用程序进程在 Android 系统中都有自己的用户标识,这是为了实现应用程序之间的隔离和安全性。

除了 App 的进程,top 的输出还包括一些用户标识为 systemuser 的进程,应当使用 grep 排除掉。通过下面的 adb shell 命令,可以得到所有的 App 进程状态:

top -b -d 1 -n 10 -s 12 | grep -v -e '^ *[0-9]* [a-tv-z]' # top: # -b batch mode,易于输出写入文件 # -H 显示线程 # -d 1 1秒刷新一次 # -n 10 刷新1次后退出 # -s 12 以第12列(即包名)排序输出 # grep: # -v 反转,匹配的不输出,筛选掉 system 和 root 的进程,只留下 user 的进程 # -e 表达式

得到这样的输出:

Tasks: 764 total, 1 running, 763 sleeping, 0 stopped, 0 zombie Mem: 5633892K total, 5129488K used, 504404K free, 197612K buffers Swap: 4194300K total, 925376K used, 3268924K free, 1724040K cached 800%cpu 11%user 0%nice 33%sys 750%idle 0%iow 5%irq 1%sirq 0%host PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+[ARGS] 4510 u0_a71 20 0 4.9G 48M 30M S 0.0 0.8 0:00.57 system 2906 u0_a203 20 0 5.3G 44M 38M S 0.0 0.7 0:05.54 org.codeaurora.ims 24964 u0_a312 10 -10 5.6G 169M 128M S 2.0 3.0 0:24.91 mark.via 4703 u0_a117 20 0 4.9G 48M 31M S 0.0 0.8 0:00.54 com.xiaomi.xmsfkeeper 6011 u0_a160 20 0 5.1G 50M 36M S 0.0 0.9 0:03.28 com.xiaomi.xmsf:services 5276 u0_a160 20 0 5.3G 55M 49M S 0.0 0.9 0:15.60 com.xiaomi.xmsf 27552 u0_a143 20 0 5.0G 78M 61M S 0.0 1.4 0:02.22 com.xiaomi.simactivate.service 4672 u0_a104 20 0 4.9G 56M 37M S 0.0 1.0 0:00.71 com.xiaomi.mircs ...

参数解释:

Tasks: 764 total, 1 running, 763 sleeping, 0 stopped, 0 zombie 共有764个进程,一个在运行,763个在休眠,0个已停止,0个僵尸进程 Mem: 5633892K total, 5129488K used, 504404K free, 197612K buffers 物理内存总共 5633892K,已使用 5129488K,剩余 504404K,另有 197612K 用作缓冲区 Swap: 4194300K total, 925376K used, 3268924K free, 1724040K cached 交换空间总共 4194300K,已使用 925376K,剩余 3268924K,另有 1724040K 用作缓冲区 800%cpu 11%user 0%nice 33%sys 750%idle 0%iow 5%irq 1%sirq 0%host CPU共有800%负载,用户占11%,高优先级进程占0%,系统占33%,空闲750%,IO等待占0%,硬中断占5%,软中断占1%,其它占0% PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ [ARGS] 进程ID 用户名 优先级 NICE值 虚拟空间大小 常驻内存用量 共享内存用量 进程状态 CPU使用率 内存使用率 CPU时间 进程参数 24964 u0_a312 10 -10 5.6G 169M 128M S 2.0 3.0 0:24.91 mark.via NI(Nice 值)表示进程的优先级。Nice 值是一个用于调整进程优先级的参数,取值范围从 -20 到 19,其中 -20 表示最高优先级,19 表示最低优先级。 TIME+ 显示的进程自启动以来累计使用的 CPU 时间,包括用户态和内核态的时间。

top 的输出中,我们就可以得到所有 App 的优先级、内存占用、CPU 使用时间,并且能每秒刷新一次,这可以给我们许多信息!

例如,当「百度地图」切换到后台,top 的输出显示,「百度地图」的进程仍在后台长时间占用 CPU 资源,我都已经锁屏 5 分钟了,它还在占着 4% 的 CPU。不愧是大厂作风。

此外,还可以观察到进程占用内存的动态减少过程,以此,就可以得知系统杀了哪些后台进程。

adb shell 中,通过管道,可以将 top 的输出写到文件:

# 先把此刻的时间写入 log date > /sdcard/log.txt # 间隔1秒,输出120次,即持续监控2分钟,结果追加到 log top -b -d 1 -n 120 -s 12 | grep -v -e '^ *[0-9]* [a-tv-z]' >> /sdcard/log.txt

然后把日志文件拉到电脑;

adb pull /sdcard/log.txt log.txt

综合分析

结合前台 App、后台进程的动态 log 数据,就可以得到更多的信息,如:

  1. 在前台打开某个 App 时,后台哪几个 App 进程的内存占用显著减少,疑似被系统强制杀死,这就可以精确到某 App 是在哪个时刻被杀死的
  2. 哪些 App 切换到后台时,还在一直疯狂占用 CPU,彰显大厂作风
  3. 制作进程状态的动态视频

不过这些分析不是我的强项,就不进一步做了(我还没学 Python 数据制图)

  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    335 引用 • 324 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...