iOS的杀后台机制和手表App如何保活

首先要说明的是:苹果并没有公开过完整的杀后台规则,也不提供让 App 一直存活的正规方法。 iOS 的设计是:App 退到后台很快会被挂起,代码不再运行。只有系统批准的几类后台场景能继续运行或者被系统唤醒。 苹果有公开这些场景的开发文档,但什么时候杀后台、按什么顺序杀后台的策略没有公开,而且可能会随着 iOS 版本调整。

挂起 Suspended

挂起指的是 App 还占着内存、多任务界面里也还在,但进程被冻住(不跑代码、定时器、网络)。 挂起的 App 几乎不耗电,只占 RAM。内存不够的时候,系统会直接回收这块内存,不会再给 App 任何回调。

App 会有这样的状态变化:

  • Active:在前台正常运行
  • Inactive:界面还在但暂时不接受触摸,比如用户下拉了通知中心
  • Background:已经不在前台了,代码还能跑大概几秒钟的时间。调用 beginBackgroundTask 可以再要大约 30 秒
  • Suspended:Background 时间用完,系统把进程冻住的状态
  • Not running:没有运行,打开会是冷启动

Suspended 和 Background 的区别是代码还有没有在跑。

以下资料来自苹果的文档、WWDC 讲过的内容和业界经验。

系统怎么处理后台 App

  • 切到后台,默认几秒钟后 App 就会被挂起。调用 beginBackgroundTask 可以申请一小段额外的时间,现在大概是 30 秒。时间用完还不调用 endBackgroundTask,App 会被看门狗直接杀掉。

  • 内存紧张的时候,系统优先杀已经挂起的 App,占内存大的先杀。所以后台占内存越小,活得越久。

  • 在后台长时间高 CPU 负载运行会被杀。

  • 后台调度由系统决定,没法保证。BGAppRefreshTask 什么时候跑,取决于用户使用习惯、电量、低电量模式,以及用户在设置里是否关闭了后台 App 刷新等。

能够合法在后台运行的场景

  • 真正在播放音频或录音
  • 持续定位
  • VoIP(Voice over IP,网络电话)
  • 蓝牙配件
  • MFi 配件(Made for iPhone/iPad)
  • 由系统择机调度的短任务或者较长的维护任务(BackgroundTasks)
  • 静默推送唤醒,但频率会被系统限制

iOS 26 新增 BGContinuedProcessingTask:用户主动发起的长任务,比如文件导出和上传,可以在后台继续做完,系统会显示进度。

注意:播放无声音频、在不需要的时候持续定位、滥用 VoIP 保活,都会被 App Store 处理。

手表配套 App 怎么做

最正规的方案是上面提到的蓝牙配件方案,加上 Core Bluetooth 的状态保存和恢复。

  • 创建 CBCentralManager 时传入 CBCentralManagerOptionRestoreIdentifierKey。这样 App 在后台被系统回收后,只要出现蓝牙事件,系统会在后台重新拉起 App,并把之前的连接状态交给 App。

  • 断开蓝牙后对已知设备调用 connect(peripheral)。这个请求不会超时,设备重连后系统会自动唤醒 App,挂起也有效。这是蓝牙 App 能够长时间保持在线的关键。

  • 连接保持期间,手表每发一次 notify,App 就会被唤醒一小段时间(约 10 秒)来处理数据。但处理要尽早结束,不要趁机干重活。

  • 通过 ANCS、CTS、AMS 不依赖 App 运行来给手表推送信息。

notify 是一个可以善加利用的机制,比如可以用来更新运动信息,这样就可以用较高的频率让 iOS 唤醒 App。这样还有个好处是符合用户的习惯:人活动的时候感觉 App 很稳,不动的时候也许是不戴表了,就不会那么频繁被唤醒。