如果你已经写过 Java 层的 Binder 调用,但一碰到 libbinder 里的 BnInterface、IInterface 就发怵,这门课正好补上那块缺口。它不教你如何注册一个系统服务,也不讲 ServiceManager 的启动流程,而是把镜头对准一件事:Native 系统服务的 API 到底该怎么设计。换句话说,当你要写一个供其他进程调用的 C++ 服务时,接口的骨架应该长成什么样,为什么非要套一层 IBinder,又为什么 Stub 类能省掉你一半的重复劳动。

先搞清楚自己缺什么

这门课适合已经会写简单的 Android 应用、也知道 Binder 是进程间通信机制,但还没亲手写过 Native 服务的人。如果你连 sp<> 和 wp<> 都还没见过,建议先补一下智能指针和 Binder 基础,否则看前两个单元会有些吃力。课程从“Native 系统服务的角色”切入,它先帮你把服务端、客户端、Binder 驱动这三者之间的关系重新梳理一遍,然后直接带你写一个 SQRService。这个服务不是玩具,它把设计步骤拆得很细:从定义接口、实现 IBinder,到把接口特殊化,每一步都让你看到为什么 Java 层那种 aidl 自动生成的模式,在 Native 层要手动来一遍。

建议你先看第 3 单元“亲自撰写 SQRService 服务”和第 4 单元“将 IBinder 接口特殊化”。这两块是整门课的骨架,前者让你明白一个服务从零开始要写哪些方法,后者告诉你为什么要用 IInterface 把通用的 IBinder 变成带业务能力的接口。看完这两个单元,你再去回看第 1、2 单元,会有“原来如此”的感觉。

学完能独立做什么

学完之后,你应该能独立完成下面这件事:在 frameworks/native 下新增一个 Native 服务,定义自己的业务接口,写一个 Stub 类来承接客户端请求,并且通过 defaultServiceManager() 把服务注册出去。你不需要再依赖 aidl 工具生成 C++ 代码,而是能手写或者用模板生成 Stub 类。更重要的是,你能看懂系统里已有的 Native 服务(比如 SurfaceFlinger 或 AudioFlinger)的接口头文件,知道它们为什么那样组织代码。

课程最后两个单元专门讲“使用模板产生 Stub 类”和“以既有的 Native 服务为例”,它们是检验你能否举一反三的地方。模板生成不是让你背命令,而是让你理解 IMediaPlayer 这类接口的 Bp 和 Bn 是怎么来的。如果你能把模板生成的过程和手写的过程对应上,说明你真正掌握了这套 API 设计的逻辑。

资料怎么配合练习

这份资料包里没有现成的可运行工程,它更像一套跟着动手的讲义。建议你打开课程的同时,在电脑上建一个 libbinder 的源码目录,对照着第 3 单元把 SQRService 的代码逐行敲一遍。不要只复制粘贴,因为这门课的重点不是代码本身,而是每一步的决策理由。敲完之后,你可以在 frameworks/native/libs/binder/tests 里找一个现成的测试文件,试着把你的服务加进去,用 service_manager 查一下能不能注册成功。

练习时建议把第 5 单元“设计 Stub 类”和第 6 单元“使用模板产生 Stub 类”放在一起看。先手写一个 Stub,再跑一遍模板生成,对比一下差异。你会发现模板生成的代码里有一些 CHECK_INTERFACE 之类的宏,这些宏的作用在第 5 单元里讲得很清楚。如果你跳过了手写直接看模板,很容易被宏搞晕。最后,用第 7 单元里的既有服务做参照,把你写的服务改成类似的接口风格,看看能不能让客户端通过 sp<ISQRService> 正常调用。这个过程能帮你把“接口设计”从抽象概念变成肌肉记忆。

如果你卡在某个单元,不要急着往后看。这门课的节奏很紧凑,每一个单元都在为下一个单元铺垫。比如第 4 单元没搞懂,第 5 单元设计 Stub 时就会混乱。宁可多花时间把 IBinder 和 IInterface 的关系理顺,也不要囫囵吞枣。学完

课程目录

1 单元-1_Native系统服务的角色 (14:39)
2 单元-2_提供通用性的IBinder接口 (09:55)
3 单元-3_亲自撰写SQRService服务 (32:14)
4 单元-4_将IBinder接口特殊化 (09:45)
5 单元-5_设计Stub类 (08:21)
6 单元-6_使用模板产生Stub类 (12:21)
7 单元-7_以既有的Native服务为例 (09:09)