Android 15进程冻结机制全解析:触发、解冻与开发者适配

发布时间:2026/9/17 2:28:55

Android 15进程冻结机制全解析:触发、解冻与开发者适配 1. Android V冻结到底冻的是什么先纠个偏拿到Android15 AndroidV冻结和解冻这个标题不少人的第一反应是怎么在Android 15上冻结App——我一开始也有这个条件反射毕竟冻结这个词太常出现在用户教程里了。但实际上Android V冻结指的是Android 15代号Vanilla Ice Cream简称Android V系统层面的进程冻结机制Process Freezer不是你用第三方工具手动把某个应用冻起来那种操作。这里有个特别大的概念混淆。你在网上看到红米K70能用adb冻结吗澎湃OS能用adb冻结应用吗这种热词它们说的是用户主动通过adb shell pm disable-user或者App Ops权限去停用/冻结某个应用本质上是把应用从系统里摘出去让它彻底没机会运行。而AndroidV冻结是系统自己在运行时根据进程状态和资源情况把某些后台进程临时放到冰柜里不调度、不执行但内存还在、状态还在等需要的时候再解冻恢复。一个是人主动操作一个是系统自动决策完全是两码事。这种冻结的语义其实在很多领域都有。就像PyTorch里冻结部分模型参数是把某些层的梯度计算停掉模型结构不变、权重不变只是不再参与训练更新永磁体控制里冻结磁导率则是把磁链表固定住用于参数辨识甚至连库存管理里都有冻结库存——账还在但不能动。这些概念的核心逻辑是相通的冻结不是销毁而是暂停使用保留恢复能力。所以本文要聊的冻结和解冻场景是Android系统级的进程冻结机制。它决定了你的App在后台待了一会儿之后是被静默冻住还是被杀掉也决定了用户切回来时的恢复速度。Android 15在这个机制上有不少精细调整值得系统看一看。2. 哪些场景会把进程送进冰柜冻结触发链路细看2.1 缓存进程Cached Process的判定流程进程冻结最核心的触发源是进程进入缓存态。在Android的进程优先级体系里ActivityManagerServiceAMS会给每个进程算一个adj值OomAdjuster这个值直接决定进程的命运。当进程从前台退到后台Activity不可见、没有服务在跑、没有内容提供者被引用adj就会跌到缓存进程区间通常是CACHED_APP_MIN_ADJ到CACHED_APP_MAX_ADJ。到了Android 15系统不会立刻冻结刚退到后台的进程而是有一个阈值和延迟策略。我实测下来进程进入缓存态之后系统会先观察一段时间看它是否稳定处于后台、是否有活跃的绑定关系。如果进程在这个期间没有任何唤醒动作才会被标记为可冻结freezable。这种缓冲设计是为了避免用户快速切走又切回时产生额外的解冻开销——毕竟解冻也是有代价的频率太高反而影响体验。2.2 App Standby Bucket 带来的时段性冻结Android 15把App Standby策略和进程冷冻结合得更紧密了。按照使用频率每个应用会被分到ACTIVE、WORKING_SET、FREQUENT、RARE、NEVER这五个桶里。桶的等级越靠后进程在后台被冻结的概率越高、越快。具体到场景一个应用长期没被用户打开掉到RARE桶之后即便它还在后台跑着JobScheduler任务任务执行窗口一结束、进程回到缓存态系统就会非常果断地冻结它。这个果断的程度在Android 15里比之前版本激进不少我对比Android 14和15的日志同样一个低活跃应用退到后台Android 14可能10分钟才冻结Android 15可能3分钟就冻结了。对用户来说这是省电但对那些悄悄在后台做事比如下载、同步的App来说意味着系统更频繁地打断。2.3 Doze模式与Alarm批处理窗口叠加冻结Doze模式本身就是一套省电策略它会延迟网络和Alarm。Android 15把Doze和进程冻结做了一层叠加当设备进入Doze的维护窗口maintenance window系统会批量放行Alarm和Job让App短暂运行然后窗口一关立刻把处理器晾在一边。这里有个细节值得注意Android 15的Doze维护窗口期间如果App启动了前台服务或绑定了系统服务进程不会进入冻结候选但如果只是普通的Alarm回调、不持有任何用户可见的组件则Alarm执行完之后进程会被快速收敛为缓存态并冻结。所以开发者如果依赖Alarm做业务但回调里只是写数据、没做用户可见的事很可能在Android 15上发现任务执行了但进程很快被冻——这不是任务被吃掉而是任务的善后工作时间变短了。2.4 厂商激进策略与用户层冻结的差异这里必须提一下国内厂商的定制。澎湃OS、MIUI、ColorOS这些系统本身就有一套更激进的省电策略。它们把系统级冻结和用户可感知的冻结管理结合用户在设置里看到冻结应用选项、或者通过adb冻结应用实际上是叠加在系统冻结机制之上的另一层控制。像红米K70能用adb冻结吗这个问题答案是能用而且adb冻结确实可以实现类似的效果。但它和Android V系统冻结有本质区别adb冻结或者厂商设置的冻结是把应用标记为不可启动、不可缓存运行用户点图标都可能没反应必须手动解除而系统V冻结是运行时状态的暂停用户点进应用时系统会自动解冻不需要任何干预。所以做开发的时候要区分这两个概念否则可能会误判问题。比如用户反馈App从后台切回来卡死了如果你排查时发现进程状态是FROZEN那是系统自动冻结机制的正常表现解冻后应该能恢复但如果进程是disabled状态、连启动Activity都进不来那就是另一层问题了。3. 解冻不是恢复运行这么简单解冻触发场景梳理3.1 用户可见性恢复Activity、窗口与动画解冻最直接的触发场景是用户要看到这个App了。具体到系统流程用户点击图标或者从最近任务切换AppAMS会把目标进程的adj拉到前台同时调用进程的unfreeze操作。这里有一个容易被忽略的点解冻不是瞬间完成的。内核解冻一个进程需要遍历进程组内的所有线程逐个从TASK_FROZEN状态唤醒。如果进程本身有大量线程这个过程可能是几十毫秒。在Android 15上系统会在拉起进程的同时启动Activity的冷启动流程即使进程还在解冻过程中binder调用也会排队等进程恢复到可响应状态。所以实际感受到的冷启动时间等于IPC唤醒时间 解冻时间 Application初始化时间。此外窗口动画和过渡动画会延迟或提前解冻的时机。Android 15有个细节是如果进程在用户输入事件到达时才解冻系统会先处理输入再触发展开过渡动画避免动画期间进程还没准备好导致掉帧。实测Android 15上快速切换应用的流畅度提升有一部分正来自于这个解冻优先于动画的调度顺序。3.2 显式意图与系统回调唤醒进程被冻结后四大组件都处于不可执行状态。这时候如果有人向它发起binder调用或Intent投递系统会触发解冻。比较常见的是startActivity()显式启动ActivitystartService()/bindService()显式启动或绑定服务发送sendBroadcast()显式广播只针对显式广播隐式广播在后台受限严重ContentResolver访问进程持有的ContentProvider这里要特别提醒隐性广播在Android 15上基本不会解冻进程。系统广播比如BOOT_COMPLETED、PACKAGE_ADDED、网络状态变化在目标应用处于后台缓存态时会直接投递异常或延迟到应用下次启动而不是唤醒进程。国内很多App喜欢监听ACTION_SCREEN_ON/ACTION_SCREEN_OFF这种系统广播做业务触发在Android 15上如果进程已经被冻结这些广播根本到不了代码里。3.3 媒体会话、投屏与录音场景媒体类和录屏类的进程解冻规则比较特殊。Android 15有一个专门的机制保障只要进程持有MediaSession且正在播放音频、或者持有MediaProjection进行投屏/录屏、或者正在录音系统会把这些场景标记为高优先级活动进程不会被冻结。这背后是一整套前台服务类型的判断。但android15 无法投屏这个热搜词反映的恰恰是边界情况如果应用申请了MediaProjection但投屏过程中没有正确创建前台服务或者服务类型没有声明mediaProjection进程依然有概率被系统冻结。Android 15对前台服务类型的检查比之前严格很多targetSdk在35以上的App必须在前台服务创建后5秒内调用startForeground()并声明正确的类型否则会抛ForegroundServiceTypeException。一旦抛异常进程没有前台服务保护投屏中如果用户把App切到后台进程就很容易被冻结画面卡住、投屏断开。所以遇到投屏断连第一反应不应该是怀疑协议问题先查前台服务类型是否合规。3.4 输入法、壁纸、无障碍等系统绑定服务除了常规四大组件还有一些借宿在普通进程里的系统级组件它们也会触发解冻。典型的有输入法IME用户点击输入框系统会绑定输入法进程。即使输入法进程被冻结只要发生输入事件InputMethodManagerService会立刻解冻它。壁纸引擎WallpaperService桌面切换或壁纸需重绘时动态壁纸进程会被唤醒。无障碍服务AccessibilityService无障碍服务通常常驻但系统为了省电也可能冻结它。有用户反馈开启无障碍的App在后台被冻后导致辅助功能短暂失灵这就是解冻策略还在演进的边界场景。通知栏磁贴TileService用户下拉通知栏并点击磁贴时即使进程冻结也会被解冻。这些场景的解冻有一个共同点用户可见的系统UI交互有最高解冻优先级。系统会先解冻再执行binder调用确保UI层无感知。4. 从AMS到内核freezer cgroup冻结解冻在系统里是走哪条路4.1 冻结请求的发起与传递路径理解了触发场景接下来要把整个链路串起来。一次标准的冻结请求大致经过这些环节ActivityManagerService (判定进程为缓存态/低活跃) └─ OomAdjuster (计算adj更新进程状态) └─ ProcessRecord (标记进程为freezable) └─ ProcessFreezer (调用freezer接口) └─ cgroup freezor (写入freezer.state) └─ 内核调度器 (将进程所有线程标记为TASK_FROZEN)Android 15在ProcessRecord里维护了一套状态机进程状态会经历FREEZABLE→FREEZING→FROZEN→THAWING→UNFROZEN。系统要求冻结和解冻必须走完整的异步回调链路不能直接同步切换——因为进程可能正在执行binder事务贸然冻结会打断事务导致异常。我在实际调试中看到Android 15会打印类似freeze process xxx (pid) in provider call这样的信息意思是进程当前正持有binder事务锁需要等事务完成才能进入冻结。这解释了为什么你会在logcat里看到冻结动作延迟几十毫秒甚至几百毫秒——系统在等待进程内部事务收敛。4.2 内核侧TASK_FROZEN与freezer state内核层面的实现用的是cgroup v1/v2的freezer子系统具体取决于设备内核配置。冻结时向/sys/fs/cgroup/freezer/uid/pid/freezer.state写入FROZEN解冻时写入THAWED。用户态通过freezer cgroup的freeze操作让内核把目标进程组的所有线程状态切换为TASK_FROZEN。这个机制有几个特点值得展开。第一冻结的单位是进程组不是单个线程。系统以UID为粒度组织cgroup同一个应用的所有进程包括:分隔的辅助进程、pushservice、remote等会被一起冻结。第二冻结状态对进程自身透明——进程以为自己在正常等待时间片但内核不再调度它直到解冻。第三无可延迟的锁等待如果进程持有mutex或spinlock正处于临界区内核会等待锁释放再冻结避免死锁。4.3 LMKD、PSI监控与杀进程前的冻结试探低内存杀手守护进程LMKD和冻结机制在Android 15上是协同工作的。LMKD通过PSIPressure Stall Information监控内存压力当系统内存紧张时它不会立刻杀进程而是先看候选进程是否处于冻结状态。冻结状态的进程不占用CPU但占内存所以LMKD的杀进程优先级里已冻结进程往往排在可冻结进程之后。有一个反直觉的现象某些场景下LMKD会把冻结的进程杀了而不是解冻它。比如系统内存极度紧张需要批量回收内存时冻结进程由于其低活跃特性反而成为第一个被杀的对象——因为杀掉冻结进程不需要走解冻流程内核和AMS的开销最小。这就导致有用户发现明明App在后台被冻住了几分钟后回来发现它还是被杀了。实际上冻结状态并不是免死金牌它只是延迟了被杀时间。这个过程在日志里通常表现为lmkd: Kill com.example.app (pid 12345), uid 10086, freeze state: FROZEN, oom_adj 900如果你在logcat里看到类似的记录不需要慌张这是系统正常的内存回收策略。5. 现场排查实录dumpsys、logcat与常见故障定位5.1 查看进程冻结状态和冻结原因的入口排查冻结问题最常用的命令是dumpsys activity processes。它会列出每个运行中进程的状态、adj值、是否处于冻结状态。输出里重点看这几项state: 当前进程的活动状态比如CACHED、PERCEPTIBLE、SERVICEadj: OomAdjuster计算出来的优先级数值procState: 更精细的进程状态PROCESS_STATE_CACHED_EMPTY等frozen: 是否处于冻结状态另外可以看dumpsys activity exit-info查看进程被杀原因以及dumpsys activity oom查看AMS视角的进程管理信息。如果只想确认某个进程是否被冻结直接看/proc/pid/cgroup里的freezer状态也行——不过需要root权限。冻结和解冻事件本身在logcat里搜ActivityManager标签关键词freeze和unfreeze。Android 15的日志会比之前详细会打出冻结原因adb logcat -s ActivityManager | grep -E freeze|unfreeze会看到类似ActivityManager: Freezing uid 10123: cached app / state change ActivityManager: Unfreezing uid 10123: comes to foreground5.2 案例一Android 15无法投屏的冻结定位有个真实的排查案例应用升级到targetSdk 35之后在Android 15上出现投屏到电视画面卡死、过一会儿自动断开的问题。单看MediaProjection的API调用流程是对的授权也正常但一旦把App切到后台、让投屏画面继续画面就冻住了。排查的时候看了dumpsys activity processes发现App进程状态被标记为CACHED并且frozentrue。原因一句话就能说清MediaProjection的权限拿到不等于进程受到保护。Android 15的投屏场景要求开发者创建一个声明了mediaProjection类型的前台服务并且在这个服务存活期间进程才不会被冻结。你的App只拿了MediaProjection实例没有起前台服务或者起了前台服务但类型声明错进程在后台依旧会被冻。解决办法也简单在用户授权MediaProjection之后立即启动Service并调用startForeground(id, notification, FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)。注意Android 15还要检查FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION的foregroundServiceType权限FOREGROUND_SERVICE_MEDIA_PROJECTION。补上前台服务并把进程状态提升到foregroundService之后进程就不会再被冻结投屏也恢复正常。5.3 案例二后台播放中断与通知延迟另一个常见的问题是App退后台后音乐/播客播放断了。这里要区分两种情况如果用的是MediaSession且正确调用了PlaybackState系统会把进程标记为perceptible通常不会被冻结但如果实现的是传统的AudioTrack播放、没有注册MediaSession系统无法识别你正在播放音频进程一旦退到缓存态就可能被冻结。我踩过的一个具体坑是应用在后台播放语音提示音不是正式音乐开发模式下进程一直正常但Android 15的正式版本上提示音播到一半就卡住了。排查发现是提示音播放用的只是AudioTrack 普通Service没声明mediaPlayback类型。系统在Service停止前就判定进程无前台服务类型保护随即冻结。另外一个和通知相关的坑App被冻结后Notification虽然已经由系统托管显示但如果通知需要更新比如进度条变化更新通知的binder调用会先解冻进程所以后台通知更新有时会带来额外的电量消耗。对用户来说感知到的现象就是通知更新有延迟。5.4 案例三游戏挂机/下载任务被冻住游戏挂机、长连接下载这类场景属于和Android省电策略硬碰硬的典型。排查的时候要注意长连接本身不会阻止冻结——只要进程进入缓存态且没有前台服务TCP连接还挂着线程照样被冻结网络数据来了也不会唤醒进程等解冻后数据才一次性收回来。所以如果你的App有后台下载需求一定要走WorkManager或JobScheduler配合前台服务类型dataSync。单独靠Socket长连接扛在Android 15上大概率会被冻。相反如果用了前台服务并且声明类型正确系统在冻结时会跳过被前台服务保护的进程下载任务就能稳定跑完。6. 应用开发者怎么和这套冻结机制相处适配建议与避坑经验6.1 前台服务与媒体会话的正确姿势从前面的案例能看出来和冻结机制打交道最核心的关键字就是前台服务类型。Android 15已经把前台服务类型清单收得很紧合法的类型包括前台服务类型适用场景对应权限mediaPlayback音频/视频播放FOREGROUND_SERVICE_MEDIA_PLAYBACKmediaProjection投屏/录屏FOREGROUND_SERVICE_MEDIA_PROJECTIONcamera相机采集FOREGROUND_SERVICE_CAMERAmicrophone麦克风采集FOREGROUND_SERVICE_MICROPHONEdataSync数据传输FOREGROUND_SERVICE_DATA_SYNClocation/connectedDevice等定位/外设连接对应权限进程冻结机制的设计逻辑里前台服务类型是判定用户是否感知到App存在的重要依据。你在后台做任何容易被用户感知的事情就应该用对应的前台服务类型把它宣告出来——这不只是为了合规也是因为系统会基于这个宣告跳过冻结。6.2 工作管理与setForeground的时效要求WorkManager在Android 15上的冻结适配做得比较成熟。WorkManager任务执行时系统会给进程一个Job上下文进程不会立刻被冻结但任务执行完毕后进程会迅速回到缓存态并进入冻结候选。如果你的任务结束之后还有延迟回调比如onStopped里做清理这个回调在进程冻结后可能根本不会执行。另外要注意WorkManager的setForeground()调用时效。Android 15要求放行前台服务类型的通知后在特定时间窗口内调用setForeground否则会触发崩溃。我在适配过程中遇到过PendingIntent延迟触发导致违反时效要求的崩溃最后是调整了业务逻辑把通知预创建好避免临时拼装PendingIntent耗时超过窗口期。6.3 不要对抗冻结保活思路从防杀转向防冻最后说一个理念层面的东西。过去国产App开发习惯讲保活各种黑科技双进程守护、绑定系统服务、拉活链。Android 15这套冻结机制下对抗系统冻结的收益越来越低代价却越来越高。最典型的是两个自欺欺人的做法在后台开启空前台服务系统检测到你的foregroundServiceType和你实际做的事不匹配Android 15会直接抛异常并判违规。用Alarm频繁自启动拉活Alarm本身受Doze约束进程冻结后Alarm事件不会执行等到维护窗口才会批量处理根本达不到拉活目的。更合理的思路是如果你的App确实需要在后台做用户可感知的事就用合规的前台服务类型声明并正确实现如果只是普通的数据同步或定时任务就交给WorkManager让系统在最合适的时机分批执行。系统之所以冻结进程核心是相信你下次被唤醒时还能正常工作。你越是配合这套机制系统对你的调度反而越稳定。我个人在Android 15适配过程中最大的体会是冻结和解冻是一对双刃剑。它确实省电、确实让系统轻快但代价是应用在某些场景下的后台能力被大幅收窄。遇到问题先不要急着骂厂商或者怪系统打开日志看一眼进程的freeze状态很多时候答案就在那几行日志里。如果你正在适配targetSdk 35我建议把本文里提到的前台服务类型清单打印出来贴在工位上踩坑的时候对照着看能省不少时间。
延伸阅读

更多相关文章

2026/9/17 2:28:55

RevokeMsgPatcher 防撤回补丁:从安装到生效的完整操作流程

RevokeMsgPatcher 防撤回补丁:从安装到生效的完整操作流程 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: https://gitcod…

2026/9/17 2:28:55

OpenMontage视频混剪工具完整上手指南:从安装到批量出片

很多人下载完OpenMontage,第一反应是把安装包解压,然后双击主程序,接着就盯着软件界面发呆——这跟我初次接触它的时候一模一样。这个工具的名字看着有点学术味,实际上它解决的是视频创作里最朴素、但磨人的需求:把一堆…

2026/9/17 3:28:58

Vue 3 核心 API 解析:defineComponent 与 defineAsyncComponent 实战指南

前两天帮同事排查一个奇怪的问题:他写了一个 Vue 3 组件,函数命名也对、组件也正常注册了,但在 IDE 里 props 和 emits 完全没有任何类型提示。他第一反应是“是不是 Volar 插件坏了”?我让他把代码发过来一看——他确实用了 defi…

2026/9/17 3:28:58

交换机端口模式详解:Access、Trunk、Hybrid与VLAN标签转发

我第一次在交换机上敲下port link-type trunk的时候,心里其实没底:为什么一个物理口非得规定成某种模式?后来复习计算机网络,再看到“端口模式”四个字,又差点把它和 TCP 端口号搞混。这个概念卡了我很久,直…

2026/9/17 3:28:58

Windows文件复制进阶:从copy到robocopy,掌握健壮的文件同步与备份命令

直接在Windows命令提示符里敲copy去复制文件,很多人第一反应就是“这不就够用了吗”。但等你真正面对几万个文件、跨磁盘拷贝、增量备份、日志记录这些需求的时候,copy命令那点能力立马就显得捉襟见肘。所以Windows其实内置了一个很多人没用过的“搬家神…

2026/9/17 3:23:58

仿美团外卖菜单实战:数据模型与RecyclerView联动全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码