You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 文档里说的“设备上正在运行的应用进程”具体指什么?
  2. 后台进程是不是不在这个列表里?
  3. 怎么才能获取设备上所有正在运行的进程(包括后台进程)?

解答

1. 文档中“正在运行的应用进程”的实际含义

首先得明确,runningAppProcesses的实际行为和文档描述有不小的偏差,尤其是高版本Android。从Android 8.0(API 26)开始,系统对进程可见性做了严格限制:

  • 它返回的是当前应用有权限看到的进程,而不是设备上所有在运行的进程。
  • 只有和当前应用有明确交互关系的进程才会被返回,比如当前应用本身、绑定了当前应用服务的进程、处于前台的进程等。
    Google文档的描述比较宽泛,实际要结合系统版本和权限来看,它更准确的定位是“当前应用能感知到的活跃进程列表”。

2. 后台进程是否被包含?

答案是:绝大多数情况下不包含。

  • 从API 26开始,除非后台进程和你的应用有直接关联(比如你启动过它的Activity、绑定过它的服务),否则系统会隐藏这些进程的信息,这是隐私和安全机制的一部分。
  • 就算是在更低版本的Android上,runningAppProcesses也不会返回所有后台进程——那些处于缓存状态、没有活跃组件(Activity/Service等)的进程,会被系统排除在外,这类进程随时可能被回收,系统不会对外暴露它们的信息。

3. 获取所有正在运行进程的可行方案

如果你确实需要获取完整进程列表,有几种方式,但都有各自的限制:

  • 执行ps Shell命令(需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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:47:51