在 Android 系统中,每一个应用程序都是由一些 Activity 和 Service 组成的,一般 Service 运行在独立的进程中,而 Activity 有可能运行在同一个进程中,也有可能运行在不同的进程中。那么,不在同一个进程的 Activity 或者 Service 是如何通信的呢?这就是本文中要介绍的 Binder 进程间通信机制了。
我们知道,Android 系统是基于 Linux 内核的,而 Linux 内核继承和兼容了丰富的 Unix 系统进程间通信(IPC)机制。有传统的管道(Pipe)、信号(Signal)和跟踪(Trace),这三项通信手段只能用于父进程与子进程之间,或者兄弟进程之间;后来又增加了命令管道(Named Pipe),使得进程间通信不再局限于父子进程或者兄弟进程之间;为了更好地支持商业应用中的事务处理,在AT&T 的 Unix 系统 V 中,又增加了三种称为“System V IPC”的进程间通信机制,分别是报文队列(Message)、共享内存(Share Memory)和信号量(Semaphore);后来 BSD Unix 对“System V IPC”机制进行了重要的扩充,提供了一种称为插口(Socket)的进程间通信机制。若想进一步详细了解这些进程间通信机制,建议参考 Android 学习启动篇一文中提到《Linux内核源代码情景分析》一书。
但是,Android 系统没有采用上述提到的各种进程间通信机制,而是采用 Binder 机制,难道是因为考虑到了移动设备硬件性能较差、内存较低的特点?不得而知。Binder 其实也不是 Android 提出来的一套新的进程间通信机制,它是基于 OpenBinder 来实现的。OpenBinder 最先是由 Be Inc. 开发的,接着 Palm Inc. 也跟着使用。现在 OpenBinder 的作者 Dianne Hackborn 就是在 Google 工作,负责 Android 平台的开发工作。
前面一再提到,Binder 是一种进程间通信机制,它是一种类似于 COM 和 CORBA 分布式组件架构,通俗一点,其实是提供远程过程调用(RPC)功能。从英文字面上意思看,Binder 具有粘结剂的意思,那么它把什么东西粘结在一起呢?在 Android 系统的 Binder 机制中,由一系统组件组成,分别是 Client、Server、Service Manager 和 Binder 驱动程序,其中 Client、Server 和 Service Manager 运行在用户空间,Binder 驱动程序运行内核空间。Binder 就是一种把这四个组件粘合在一起的粘结剂了,其中,核心组件便是 Binder 驱动程序了,Service Manager 提供了辅助管理的功能,Client 和 Server 正是在 Binder 驱动和 Service Manager 提供的基础设施上,进行 Client-Server 之间的通信。Service Manager 和 Binder 驱动已经在 Android 平台中实现好,开发者只要按照规范实现自己的 Client 和 Server 组件就可以了。说起来简单,做起难,对初学者来说,Android 系统的 Binder 机制是最难理解的了,而 Binder 机制无论从系统开发还是应用开发的角度来看,都是 Android 系统中最重要的组成,因此,很有必要深入了解 Binder 的工作方式。要深入了解 Binder 的工作方式,最好的方式莫过于是阅读 Binder 相关的源代码了,Linux 的鼻祖Linus Torvalds 曾经曰过一句名言 RTFSC:Read The Fucking Source Code。
虽说阅读 Binder 的源代码是学习 Binder 机制的最好的方式,但是也绝不能打无准备之仗,因为 Binde r的相关源代码是比较枯燥无味而且比较难以理解的,如果能够辅予一些理论知识,那就更好了。闲话少说,网上关于 Binder 机制的资料还是不少的,这里就不想再详细写一遍了,强烈推荐下面两篇文章:
Android 深入浅出之 Binder 机制
Android Binder 设计与实现 – 设计篇
Android 深入浅出之 Binder 机制 一文从情景出发,深入地介绍了 Binder 在用户空间的三个组件 Client、Server 和 Service Manager 的相互关系,Android Binder 设计与实现 – 设计篇 一文则是详细地介绍了内核空间的 Binder 驱动程序的数据结构和设计原理。非常感谢这两位作者给我们带来这么好的 Binder 学习资料。总结一下,Android 系统 Binder 机制中的四个组件 Client、Server、Service Manager 和 Binder 驱动程序的关系如下图所示:
1、Client、Server 和 Service Manager 实现在用户空间中,Binder 驱动程序实现在内核空间中
2、Binder 驱动程序和 Service Manager 在 Android 平台中已经实现,开发者只需要在用户空间实现自己的 Client 和 Server
3、Binder 驱动程序提供设备文件 /dev/binder 与用户空间交互,Client、Server 和 Service Manager 通过 open 和 ioctl 文件操作函数与 Binder 驱动程序进行通信
4、Client 和 Server 之间的进程间通信通过 Binder 驱动程序间接实现
5、Service Manager 是一个守护进程,用来管理 Server,并向 Client 提供查询 Server 接口的能力
至此,对 Binder 机制总算是有了一个感性的认识,但仍然感到不能很好地从上到下贯穿整个 IPC 通信过程,于是,打算通过下面四个情景来分析 Binder 源代码,以进一步理解 Binder 机制:
1、Service Manager 是如何成为一个守护进程的?即 Service Manager 是如何告知 Binder 驱动程序它是 Binder 机制的上下文管理者。
2、Server 和 Client 是如何获得 Service Manager 接口的?即 defaultServiceManager 接口是如何实现的。
3、Server 是如何把自己的服务启动起来的? Service Manager 在 Server 启动的过程中是如何为 Server 提供服务的?即IServiceManager::addService 接口是如何实现的。
4、Service Manager 是如何为 Client 提供服务的?即 IServiceManager::getService 接口是如何实现的。
在接下来的四篇文章中,将按照这四个情景来分析 Binder 源代码,都将会涉及到用户空间到内核空间的 Binder 相关源代码。这里为什么没有 Client 和 Server 是如何进行进程间通信的情景呢? 这是因为 Service Manager 在作为守护进程的同时,它也充当Server 角色。因此,只要我们能够理解第三和第四个情景,也就理解了 Binder 机制中 Client 和 Server 是如何通过 Binder 驱动程序进行进程间通信的了。
为了方便描述 Android 系统进程间通信 Binder 机制的原理和实现,在接下来的四篇文章中,我们都是基于 C/C++ 语言来介绍Binder 机制的实现的,但是,我们在 Android 系统开发应用程序时,都是基于 Java 语言的,因此,我们会在最后一篇文章中,详细介绍 Android 系统进程间通信 Binder 机制在应用程序框架层的 Java 接口实现:
5、Android 系统进程间通信 Binder 机制在应用程序框架层的 Java 接口源代码分析。
转载自:
http://blog.csdn.net/luoshengyang/article/details/6618363