写在前面
- 本文集中讲的是 Native 层的 Binder 通信以及 Service
- Java 层的在下一篇里单讲
理论基础
1. 服务是什么?
- 可以简单的把服务理解为进程里的一个对象,它能干活,而且能被别的进程“引用”。
- 比如你搞了个进程,里面 new 了一个 MyWorker 对象,该对象可以被其他进程“引用”,并调用它的
do_work()
函数来干活。那么这个对象就是一个服务。
- 一个对象想成为“服务”的必要条件是:
- 能被其他进程引用,在 Binder 系统里,代表着它必须继承自 IBinder 类。这样它就能通过 onTransact() 跟引用它的进程通信。
- 能提供业务能力,即能干活,这说明它必须同时继承自某个业务类。这样引用它的进程就能通过 transact() 来“调用”它的业务函数。

- 如上图所示,一个 MyWorker 对象可以成为一个服务。
2. Binder 是什么?
- 把 Binder 理解为一个管道,它能连通两个进程,一个进程是 Server 端,另一个是客户端。
- Server 端里有一个 IBinder 类型的对象,客户端可以拿到一个“指向它的指针”。当然不是真的指向,而是逻辑上的。因为只有在同一个进程里,才能用一个指针指向一个对象。

- 图中的虚线表示这是逻辑上的指向。实线表示实际数据流是通过 Binder 传送的。
- 当 Client 端调用了 b 的 transact() 函数时,Server 端的 onTransact() 函数会被调用,并把 Client 端的参数传进来。
- 比如,Client 可以在 transact() 的参数里写上“DOWORK”,Server 端在 onTransact() 里看到参数“DOWORK”,则去调用自己的
do_work()
函数干活。
- 那么现在的问题是,如何在一个 Client 进程里,弄一个指针 b,指向另一个进程(Server)的对象呢?答案就是:ServiceManager。
3. ServiceManager 是什么?
- Android 提供了一个 ServiceManager,服务端向它注册服务,客户端从他得到服务。
- ServiceManager 只认识 Binder,向它注册服务时,要提供 IBinder 类型的对象;向它获取服务时,返回的是 IBinder 类型的指针。

- 上图说明了 Client 进程指向 Server 进程里的对象这条虚线“指针”,是通过 ServiceManager 建立的。
实际使用:最简模型
1. 服务端注册服务
- 注册服务使用 ServiceManager 的 addService() 函数,原型如下
status_t addService(const String16& name, const sp<IBinder>& service)
- 注册服务需要提供2个东西:
- 服务名称,是个字符串。
- 指向务的指针,是
sp<IBinder>
类型
- 比如我们注册一个自己的服务:
sp<IServiceManager>sm = defaultServiceManager();
sm->addService("my.serv", new MyWorker());
- 以上语句在 ServiceManager 里注册了一个名为 “my.serv” 的服务,该服务的提供者就是一个 MyWorker 对象。以后客户端拿到该服务,就能使用 MyWorker 对象的业务函数
do_work()
了。
- 另外注意,我们使用了 Android 提供的 defaultServiceManager() 函数来得到一个 ServiceManager 的实例,然后调用它的 addS