2
0

为什么 iOS 跳转更顺手,而 Android 更像一个开放路由器?

2026-06-14

从 Intent 到 XPC:不同操作系统如何让进程互相说话

很久以前我学操作系统的时候,对“进程间通信”的理解很朴素:管道、消息队列、共享内存、信号量、Socket,大概就是进程之间传数据的几种办法。这个理解当然没错,但它只覆盖了 IPC 最底层的一面。

如果把视角从内核 API 拉到真实的用户体验,就会发现一个更有意思的问题:我们每天用手机时,很多所谓的“跳转”“分享”“打开另一个 App”“调用系统能力”,本质上都是操作系统在帮不同进程之间建立一次受控通信。

比如,在浏览器里点一个链接直接打开淘宝;在微信里点击地图位置打开高德;从相册把图片分享到另一个 App;从系统搜索进入某个 App 的具体页面;用快捷指令触发某个应用内部动作。这些看起来不像传统操作系统课上的 IPC,但它们都在处理同一个问题:一个进程如何在不破坏隔离的前提下,请求另一个进程完成某件事。

所以这篇文章不打算写成“IPC API 大全”。我更想从 iOS、Android、Windows、Linux、macOS,再顺带聊聊鸿蒙,看看不同系统是如何在安全、开放性、稳定性和体验之间做取舍的。

一、IPC 的本质:隔离之后的重新连接

现代操作系统首先要做的是隔离。

每个进程有自己的虚拟地址空间,不能随便读写别人的内存。每个应用有自己的权限边界,不能随便调用别的应用内部逻辑。移动系统还进一步引入沙盒,把 App 的文件、权限、后台行为、组件暴露都管起来。

但系统不能只有隔离。一个完全互不通信的系统是没法用的。

浏览器需要把文件交给下载管理器,App 需要调用系统相机,输入法需要给当前应用输入文字,桌面程序需要调用系统服务,手机 App 需要跳转支付、地图、登录、分享。于是 IPC 就出现了:它不是隔离的反面,而是隔离之后经过授权、约束和抽象的重新连接。

从这个角度看,IPC 可以分成几层。

最底层是传输机制,比如管道、共享内存、Unix domain socket、Mach message、Binder、Named Pipe。它们解决的是“字节、句柄、消息如何从一个进程到另一个进程”。

中间层是调用模型,比如 RPC、COM、D-Bus、XPC、Binder interface。它们解决的是“能不能把跨进程通信包装得像调用一个对象或服务”。

最高层是用户动作模型,比如 Android Intent、iOS Universal Links、iOS App Intents、HarmonyOS Want。它们解决的是“一个应用如何表达我要打开、分享、支付、搜索、导航、启动某个能力”。

我们平时感知到的“跳转舒服不舒服”,通常不是底层 IPC 性能的问题,而是最高层抽象设计的问题。

二、Android:开放世界里的 Intent 路由系统

Android 最有代表性的跨组件通信机制是 Intent。

从开发者角度看,Intent 是一个消息对象。它可以用来启动 Activity,启动或绑定 Service,也可以发送 Broadcast。[1] 但从系统设计角度看,Intent 更像是一套路由协议:一个应用不一定要知道目标应用是谁,它只需要描述“我要做什么”,系统再根据已安装应用的声明去匹配能够处理这个动作的组件。

这就是 Android 很开放的地方。

比如一个 App 想打开网页,可以发出一个 ACTION_VIEW 的 Intent,带上一个 URL。系统会根据浏览器、App Link、用户默认设置、Intent filter 等信息决定谁来处理。一个 App 想分享文本或图片,也可以发出分享 Intent,让系统展示所有可接收的应用。一个应用还可以显式指定目标组件,直接打开某个包名下的 Activity。

这种设计很强,因为它把应用生态变成了一个可组合的能力市场。每个 App 都可以声明“我能处理什么”,其他 App 可以通过系统去发现和调用这些能力。Android 的“开放感”很大程度上就来自这里。

但开放也带来了代价。

第一,跳转可能有歧义。多个 App 都声明自己能处理同一种链接或动作,系统就需要让用户选择。第二,不同厂商系统、默认应用、浏览器、WebView、权限策略可能让跳转行为变得不一致。第三,如果开发者 Intent filter 配得过宽,或者导出组件控制不严,还可能引入安全问题。

所以 Android 后来在普通 deep link 之外,又强化了 Android App Links。App Links 的核心是通过网站和 App 之间的可信关联来证明“这个域名确实属于这个 App”,验证成功后,链接可以直接打开对应 App 内容,减少选择器干扰。[2]

这其实就是 Android 在开放和确定性之间的折中:普通 Intent 保持开放,App Links 增加可信绑定。

如果用一句话概括 Android 的风格,我会说:

Android 的跨进程跳转像一个开放路由器。它允许应用声明能力,也允许其他应用按动作寻找能力。它的优点是灵活,缺点是路径不一定总是稳定。

三、iOS:更少入口,更强约束,更稳定的语义接力

iOS 也有跨 App 跳转,但它给人的感觉通常更“收束”。

早期常见方式是 URL Scheme。一个 App 注册自己的 scheme,比如 myapp://something,其他 App 可以让系统打开这个 URL,由系统转交给对应 App。这个机制简单直接,但有几个问题:scheme 可能冲突,语义不够标准,安全校验也有限。

所以 Apple 更推荐 Universal Links。Universal Links 的思路是让 App 和网站建立关联。当用户点击一个符合规则的网页链接时,系统可以直接打开对应 App,并把启动信息交给应用处理。[3] 从用户角度看,它像是“点了一个普通网页链接,但系统知道应该交给 App”。从设计角度看,它比自定义 URL Scheme 更强调可信绑定和语义一致性。

这也是 iOS 跳转体验往往更稳定的原因之一。它不是没有 IPC,也不是技术上比 Android 神秘,而是 Apple 把跨应用入口设计得更窄、更强约束、更偏系统接管。开发者能做什么、怎么做、什么时候能跳、能携带多少信息,通常都被系统框得更死。

近几年 Apple 又在推 App Intents。App Intents 的意义不只是“让 Siri 或快捷指令调用 App”,而是让应用把自己的动作和数据用结构化方式暴露给系统。[4] 也就是说,应用不再只是被一个 URL 唤醒,而是可以把“创建提醒事项”“播放某个内容”“记录一笔账”“查询某个状态”这类能力抽象成系统可理解的意图。

这和 Android Intent 的名字很像,但气质不同。

Android Intent 更像开放生态里的消息路由:谁能处理这个动作,系统帮你找。Apple App Intents 更像把 App 的能力注册成系统可编排的语义动作:系统知道你能做什么,再把你的能力接到 Siri、快捷指令、Spotlight、Widget 等入口里。

所以 iOS 的“舒服”往往不是来自更自由,而是来自更少自由。系统把不确定性提前消掉了,用户感知到的就是跳转路径更可预测、选择器更少、权限边界更清楚。

当然,这种设计也有代价。iOS 的跨 App 能力通常不如 Android 灵活。开发者不能随便暴露内部组件,也很难像 Android 那样把 App 变成一组可以被外部自由路由的 Activity。iOS 更强调系统认可的入口,而不是任意应用之间互相发现和调用。

一句话概括:

iOS 的跨进程跳转像语义接力。它不鼓励应用之间野路子互相调用,而是让系统站在中间,把链接、动作、分享、快捷指令这些入口统一管理起来。

四、Windows:一套历史包袱很重、但工程能力极强的 IPC 工具箱

如果说移动系统的 IPC 很多时候被包装成“跳转”和“调用能力”,那 Windows 更像一个庞大的 IPC 工具箱。

Windows 有很多 IPC 机制:剪贴板、窗口消息、匿名管道、命名管道、文件映射、Mailslot、RPC、COM、Socket 等。[5] 这些机制背后对应的是 Windows 长期积累下来的桌面软件生态:GUI 程序、系统服务、后台进程、驱动辅助程序、Office 插件、浏览器组件、企业管理软件,全都需要互相通信。

其中命名管道很典型。它允许没有亲缘关系的进程通信,也可以用于客户端和服务器模型。一个进程创建一个有名字的管道,另一个知道名字的进程连接上去,就可以读写数据。[6] 这和 Unix 里的 pipe 有相似之处,但 Windows 的命名管道在服务化、权限控制、跨机器通信等方面有很强的工程属性。

RPC 和 COM 则更像 Windows 世界里的“对象化 IPC”。很多系统服务并不是让你直接发字节,而是暴露一组接口,让调用者像调用远程对象或系统组件一样使用它们。COM 更是深深嵌入 Windows 桌面生态,很多自动化、插件、系统组件交互都绕不开它。

Windows 的特点不是简单,而是兼容和工程能力强。它需要照顾几十年的软件生态,所以 IPC 机制分层复杂,历史包袱也重。安全研究里经常会遇到 Windows IPC 相关的问题,比如服务权限边界、命名对象 ACL、COM/RPC 接口暴露、低权限进程和高权限服务之间的通信面。

如果说 Android 的 Intent 体现的是移动生态的开放组合,Windows 的 IPC 体现的就是桌面系统的历史复杂性:它不是为了让用户点链接跳得舒服,而是为了让各种软件、服务和系统组件能长期共存。

五、Linux:简单原语之上长出系统级总线

Linux 的 IPC 看起来更“朴素”。

传统 Unix/Linux 提供了很多经典机制:pipe、FIFO、signal、System V message queue、POSIX message queue、shared memory、semaphore、socket 等。其中 Unix domain socket 非常重要,它用于同一台机器上的进程通信,通常比走网络栈的 TCP socket 更适合同机 IPC。[7]

Unix domain socket 有一个非常关键的能力:它不仅能传普通数据,还能传文件描述符。这个能力很 Unix,因为在 Unix 里“文件描述符”是访问很多资源的统一句柄。一个进程可以把已经打开的文件、socket 或其他资源的描述符交给另一个进程,相当于把某种访问能力传过去。

这让 Linux 的 IPC 很有“组合感”。底层机制不一定华丽,但非常通用。

到了桌面和服务层,Linux 又出现了 D-Bus。D-Bus 是一个消息总线系统,常用于桌面环境和系统服务之间通信。[8] 比如通知、蓝牙、网络管理、电源管理、桌面应用之间的状态同步,很多都可以通过 D-Bus 完成。

所以 Linux 的风格可以概括为:底层原语简单,系统组合强。你可以直接用 pipe 和 socket 写很朴素的通信,也可以通过 D-Bus 做更高层的服务发现和消息分发。它不像 iOS 那样把应用跳转体验管得很细,也不像 Windows 那样背着巨大的 COM/RPC 历史体系,但它保留了 Unix 哲学里“用简单机制组合复杂系统”的味道。

不过 Linux 在移动端体验上没有成为主流,也说明一个问题:只有底层 IPC 强不够。用户感知到的“应用跳转舒服不舒服”,还需要统一的应用模型、权限模型、链接模型、分发模型和 UI 规范。传统 Linux 桌面在这些方面长期比较分散。

六、macOS:Mach 是底座,XPC 是现代接口

macOS 和 iOS 同属 Apple 生态,但 macOS 的 IPC 更接近桌面系统。

在底层,Darwin/XNU 有 Mach 这一层。Mach 里的 port 和 port right 是非常核心的概念。粗略理解,Mach port 是通信端点,port right 则是访问这个端点的能力。拥有某种 right,才有资格向对应 port 发送消息或接收消息。[9]

这是一种很“能力安全”的设计:访问不是靠随便知道一个名字,而是靠你是否持有某个权利。macOS、iOS 很多系统机制底下都能看到 Mach 的影子。

但普通开发者一般不应该直接写 Mach IPC。Apple 更推荐更高层的机制,例如 XPC。XPC 是 Apple 平台上更现代的 IPC 方式,尤其在 macOS 上很常见。它允许应用创建由 launchd 管理的轻量 helper service,把一部分工作拆到单独进程中执行。[10]

XPC 的意义不只是通信方便,还包括稳定性和权限隔离。比如一个主应用可以把高风险解析任务、后台服务、需要不同权限的工作拆到 XPC service 里。这样即使 helper 崩溃,主进程不一定跟着崩;如果权限设计合理,也能减少一个模块出问题后影响整个应用的范围。

从这个角度看,macOS 比 iOS 更像“桌面版的 Apple IPC 哲学”:底层有 Mach,开发层有 XPC,应用层还有 URL、Universal Links、App Extension、App Group 等机制。它既保留桌面系统对复杂软件结构的支持,又继承 Apple 对沙盒和权限边界的强控制。

七、鸿蒙 / OpenHarmony:从进程间通信走向设备间通信

如果要把鸿蒙放进这篇文章,它最有意思的地方不是“有没有类似 Android Intent 的东西”,而是它把 IPC 问题进一步扩展到了分布式场景。

在 OpenHarmony 的公开文档里,IPC 和 RPC 被区分得很清楚:同一设备内的跨进程通信使用 Binder driver;跨设备的远程过程调用使用 DSoftBus driver。[11] 这就意味着,它的通信模型不只考虑“一个手机里的两个进程怎么说话”,还考虑“不同设备上的能力如何互相调用”。

在应用模型上,鸿蒙 / OpenHarmony 里有 Want。Want 可以理解成一种携带目标、动作、参数等信息的对象,用于 Ability 之间传递信息。比如一个 UIAbility 启动另一个 UIAbility 时,可以通过 Want 指定目标并携带参数。[12]

这和 Android Intent 有明显的可比性。Android Intent 是组件通信和能力路由的核心对象;HarmonyOS/OpenHarmony Want 也承担了组件间传递意图和数据的角色。不同之处在于,鸿蒙更强调分布式设备协同,因此它的 IPC/RPC 叙事天然会往“跨设备能力调用”方向延伸。

这部分如果写深,会牵扯很多鸿蒙系统架构细节。但作为博客文章,可以先抓住一个核心判断:

Android 和 iOS 主要是在解决单设备 App 生态里的跳转、分享、调用和服务组合;鸿蒙 / OpenHarmony 更想把“能力调用”扩展到多设备协同,把 IPC 从进程间通信推向设备间通信。

这也是鸿蒙话题有意思的地方。它不是简单地再造一个 Android Intent,而是试图把应用组件、系统服务、分布式软总线放在同一个“全场景”叙事里。

八、为什么 iOS 跳转经常比 Android 更舒服?

回到最开始的问题:为什么很多人会觉得 iOS 的 App 跳转比 Android 更舒服?

我觉得原因不在于 iOS 的底层 IPC 更先进,而在于它对跨应用交互的约束更强。

Android 的设计允许更多应用参与路由。一个链接、一个分享动作、一个打开文件请求,都可能有多个处理者。系统会尊重用户选择、默认应用、Intent filter 和 App Link 验证状态。这很开放,也很符合 Android 的生态性格。但开放带来的副作用就是不确定性:有时候弹选择器,有时候进浏览器,有时候进 App,有时候被厂商系统改了行为。

iOS 则倾向于减少这种不确定性。Universal Links 把网站和 App 绑定起来,App Intents 把应用能力结构化交给系统,分享和扩展入口也受到严格管理。用户感知到的是“点了就去该去的地方”,开发者感受到的是“系统不让你乱来”。

所以这不是简单的谁先进谁落后,而是设计取舍不同。

Android 更像开放路由器:生态自由度高,组合能力强,但体验一致性更难保证。

iOS 更像系统调度员:入口更少,约束更强,但路径更稳定。

Windows 更像工程工具箱:机制多、历史长、兼容强,适合复杂桌面软件和系统服务。

Linux 更像通用原语集合:简单机制之上靠组合构造复杂系统,Unix domain socket 和 D-Bus 是典型代表。

macOS 则介于桌面复杂性和 Apple 强约束之间:底层 Mach,现代 XPC,上层再配合沙盒、扩展和链接机制。

鸿蒙 / OpenHarmony 则把问题进一步推到多设备:不仅要让进程互相说话,还要让不同设备上的能力互相发现和调用。

九、结语:IPC 不是 API 名单,而是系统设计哲学

如果只背操作系统课本,IPC 可能只是一堆名词:pipe、FIFO、shared memory、message queue、socket、semaphore。

但如果从真实系统看,IPC 其实是操作系统设计哲学的集中体现。

它要回答几个问题:

进程之间应该隔离到什么程度?

一个应用能否调用另一个应用的能力?

系统应该让开发者自由组合,还是替用户收束路径?

通信应该暴露成底层字节流,还是包装成对象、服务、意图和动作?

权限应该依赖用户选择、签名验证、能力句柄,还是系统中介?

Android、iOS、Windows、Linux、macOS、鸿蒙给出的答案都不一样。

也正因为不一样,IPC 才不只是操作系统里一个很旧的章节。它其实一直在变化:从进程间传字节,到服务间 RPC;从应用跳转,到系统级动作编排;从单设备通信,到跨设备能力协同。

所以,下次再看到“从一个 App 跳到另一个 App”这种普通操作时,可以稍微多想一层:这不是简单的界面切换,而是操作系统在安全边界、生态开放性和用户体验之间做出的一次调度。

参考依据:

[1] Android 官方将 Intent 定义为用于请求另一个应用组件执行动作的 messaging object,并列出启动 Activity、启动 Service、发送 Broadcast 等基本用法。
[2] Android App Links 通过 App 与网站的可信关联,让验证后的链接直接打开 App 内容,并减少选择器干扰。
[3] Apple Universal Links 文档说明,用户触发 Universal Link 时,系统会启动 App 并传递 NSUserActivity;Apple 也说明 Universal Links 可用于 App 与网站内容关联。
[4] Apple App Intents 文档说明,App Intents 用结构化方式表达 App 的 actions 和 data,使系统能够发现和集成这些能力。
[5] Microsoft Win32 IPC 文档列出多种 Windows 进程间通信机制,包含 pipes、file mapping、RPC、clipboard、COM、sockets 等。
[6] Microsoft Named Pipes 文档说明,命名管道可用于 pipe server 与一个或多个 pipe clients 之间的一向或双向通信。
[7] Linux unix(7) 手册说明,AF_UNIX/AF_LOCAL socket family 用于同一机器上的进程高效通信。
[8] D-Bus 官方站点将 D-Bus 描述为 message bus system,用于应用之间通信。
[9] Apple Kernel Programming Guide 对 Mach port rights 的描述表明,port right ownership 是 Mach 访问控制和 IPC 的核心机制。
[10] Apple XPC 文档说明,XPC 可创建由 launchd 管理的轻量 helper tools / XPC services,为 App 执行工作。
[11] OpenHarmony 文档说明,同设备 IPC 使用 Binder driver,跨设备 RPC 使用 DSoftBus driver。
[12] OpenHarmony 的 Want / Ability 机制文档。

Comments