Android TV模拟器中ActivityManager.runningAppProcesses仅返回当前应用的技术咨询
关于ActivityManager.runningAppProcesses的困惑:为何看不到后台进程?
问题背景
我在Android TV模拟器里写了这段代码:
val am = this.getSystemService(ACTIVITY_SERVICE) as ActivityManager am.runningAppProcesses?.forEach { Logger.debug("XXX", "Running ${it.uid} , ${it.processName}, ${it.pid}") }
我已经启动了几个第三方应用但没关闭,按照Google文档的描述,ActivityManager.runningAppProcesses是用来返回设备上正在运行的应用进程列表的。但实际执行时,这个列表长度始终是1,只包含我从Android Studio启动的当前应用。我本来以为那些后台的第三方应用也会被列出来,所以想搞清楚几个问题:
- 文档里说的“设备上正在运行的应用进程”具体指什么?
- 后台进程是不是不在这个列表里?
- 怎么才能获取设备上所有正在运行的进程(包括后台进程)?
解答
1. 文档中“正在运行的应用进程”的实际含义
首先得明确,runningAppProcesses的实际行为和文档描述有不小的偏差,尤其是高版本Android。从Android 8.0(API 26)开始,系统对进程可见性做了严格限制:
- 它返回的是当前应用有权限看到的进程,而不是设备上所有在运行的进程。
- 只有和当前应用有明确交互关系的进程才会被返回,比如当前应用本身、绑定了当前应用服务的进程、处于前台的进程等。
Google文档的描述比较宽泛,实际要结合系统版本和权限来看,它更准确的定位是“当前应用能感知到的活跃进程列表”。
2. 后台进程是否被包含?
答案是:绝大多数情况下不包含。
- 从API 26开始,除非后台进程和你的应用有直接关联(比如你启动过它的Activity、绑定过它的服务),否则系统会隐藏这些进程的信息,这是隐私和安全机制的一部分。
- 就算是在更低版本的Android上,
runningAppProcesses也不会返回所有后台进程——那些处于缓存状态、没有活跃组件(Activity/Service等)的进程,会被系统排除在外,这类进程随时可能被回收,系统不会对外暴露它们的信息。
3. 获取所有正在运行进程的可行方案
如果你确实需要获取完整进程列表,有几种方式,但都有各自的限制:
- 执行
psShell命令(需Root权限):这是最直接的方式,但需要设备Root,非Root设备无法获取完整信息,甚至会触发权限异常。代码示例:
val process = Runtime.getRuntime().exec("ps") val reader = BufferedReader(InputStreamReader(process.inputStream)) var line: String? while (reader.readLine().also { line = it } != null) { Logger.debug("XXX", line ?: "") } reader.close() process.waitFor()
- 使用
UsageStatsManager(无需Root但需用户授权):如果只是想判断特定应用是否活跃,可以用这个工具类。它需要android.permission.PACKAGE_USAGE_STATS权限,且用户必须在系统设置里手动给你的应用授权“查看应用使用情况”权限。代码示例:
val usageStatsManager = getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val endTime = System.currentTimeMillis() val startTime = endTime - 1000 * 60 * 60 // 查过去1小时的使用记录 val usageStatsList = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, startTime, endTime ) usageStatsList.forEach { stats -> if (stats.lastTimeUsed > startTime) { Logger.debug("XXX", "应用 ${stats.packageName} 近期有活动") } }
这种方式拿不到PID、UID这类进程细节,但能判断应用是否处于活跃状态,适合大部分非Root场景。
最后提醒一句:Android系统一直在收紧进程信息的访问权限,这是为了保护用户隐私和系统安全。如果你的需求不是必须的,尽量避免依赖这类功能,否则在高版本Android上很容易出现兼容性问题。
内容的提问来源于stack exchange,提问作者Mr.T
相关产品推荐
相关产品推荐

