1)客户端首先获得服务器端的代理对象。所谓的代理对象实际上就是在客户端建立一个服务端的“引用”,该代理对象具有服务端的功能,使其在客户端访问服务端的方法就像访问本地方法一样。
2)客户端通过调用服务器代理对象的方式向服务器端发送请求。
3)代理对象将用户请求通过Binder驱动发送到服务器进程。
4)服务器进程处理用户请求,并通过Binder驱动返回处理结果给客户端的服务器代理对象。
5)客户端收到服务器端的返回结果。
驱动程序部分驱动程序的部分在以下的文件夹中:
kernel/include/linux/binder.h
kernel/drivers/Android/binder.c
binder驱动程序是一个miscdevice,主设备号为10,此设备号使用动态获得(MISC_DYNAMIC_MINOR),其设备的节点为:/dev/binder
在其驱动的实现过程中,主要通过binder_ioctl函数与用户空间的进程交换数据。BINDER_WRITE_READ用来读写数据,数据包中有一个cmd域用于区分不同的请求。binder_thread_write函数用于发送请求或返回结果,而binder_thread_read函数则用于读取结果。在binder_thread_write函数中调用binder_transaction函数来转发请求并返回结果。当收到请求时,binder_transaction函数会通过对象的handle找到对象所在的进程,如果handle为空,就认为对象是context_mgr,把请求发给context_mgr所在的进程。请求中所有的Binder对象全部放到一个RB树中,最后把请求放到目标进程的队列中,等待目标进程读取。数据的解析工作放在binder_parse()中实现;关于如何生成context_mgr,内核中提供了BINDER_SET_CONTEXT_ MGR命令来完成此项功能。
1. 打开/dev/binder文件:open("/dev/binder", O_RDWR);
2. 建立128K内存映射:mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
3. 通知Binder驱动程序它是守护进程:binder_become_context_manager(bs);
4. 进入循环等待请求的到来:binder_loop(bs, svcmgr_handler);
Server和Client获得Service Manager接口
frameworks/base/include/binder/IServiceManager.h
frameworks/base/libs/binder/IServiceManager.cpp
sp defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
Java接口源代码
Service Manager、Server和Client这三个角色的实现了。通常,在应用程序中,我们都是把Server实现为Service的形式,并且通过IServiceManager.addService接口来把这个Service添加到Service Manager,Client也是通过IServiceManager.getService接口来获得Service接口,接着就可以使用这个Service提供的功能了,这个与运行时库的Binder接口是一致的。
Service Manager的Java远程接口
frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
frameworks/base/core/java/com/android/internal/os/BinderInternal.java
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
frameworks/base/core/java/android/os/ServiceManagerNative.java
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}