Android进程间通信--碎碎念
2014-11-15 14:30
656 查看
感谢邓凡平老师的《深入理解Android系统》,这篇文章就是看完邓老师的第六章深入理解Binder 后的碎碎念。
Binder是什么?
Binder是Android进程间通信机制,就像共享内存,共享文件等一样,是一套IPC的机制;
Android的Binder机制是在OpenBinder开源项目实现的;
Binder机制是一个C/S的通信架构
相比于其他IPC的优势?
更好的传输性能
SOCKET:是一个通用接口,导致其传输效率低,开销大;
管道和消息队列:因为采用存储转发方式,所以至少需要拷贝2次数据,效率低;
共享内存:虽然在传输时没有拷贝数据,但其控制机制复杂;
更高的安全性
Binder机制的UID/PID是由Binder机制本身在内核空间添加身份标识,安全性高;
Binder可以建立私有通道,这是linux的通信机制所无法实现的;
Binder的整体架构:
从图中我们可以看出:
1)IPC指的是Client和Server模块之间的通信,虚线的双向箭头表示实际的数据并非Client、Server间直接传递,而是通过实线箭头传递的;
2)Client通过open、ioctl两个方法将自己需要通信的数据传入底层BinderDriver中,Server端通过open和ioctl获取Client写入BinderDriver中的数据,然后处理并再次通过Driver返回给Client;
3)ServiceManager,Binder中的老大,不负责具体通信工作,负责管理Server;
4)Binder机制实际上是虚拟了一个Binder设备,放在/dev/目录下,Client和Server通过访问BinderDriver实现互相之间的通信。
图中所能看到的问题:
1) Service Manager有什么用?
Binder通信中的老大,管理Server,系统中每个进程(Client和Server)都知道ServiceManager的位置,Server要提供服务,需要在ServiceManager中注册,Client需要什么服务需要向ServeiceManager要,这样Client和Server两端才能取得联系,互相通信;
2)Client/Server之间怎么通信的?
接下来通过一个MediaPlayerService的启动过程分析;
3)open/ioctl 做了什么?
open和ioctl是Linux驱动编程的方法,用来访问驱动程序
Client/Server之间怎么通信的?
通过MediaPlayerService的启动过程来分析Client和Server之间是怎么通信的;
// MediaPlayService 启动main函数
int main(int argc, char** argv) {
1) sp<ProcessState>proc(ProcessState::self());
2)sp<IServiceManager>sm = defaultServiceManager();
3) AudioFlinger::instantiate(); MediaPlayService::instantiate();CameraService::instantiate(); AudioPolicyService::instantiate();
4)ProcessState::self()->startThreadPool();
5)IPCThreadState::self()->joinThreadPool();
}
整个的启动分为5个部分
1 实例化一个ProcessState
2 获取一个IServiceManager对象
3 各种实例化
4 开启一个线程池
5 当前线程调用一个joinThreadPool()方法
新的问题:
1 ProcessState有什么作用?
2 IPCThreadState有什么作用?
3 IserviceManager明显是个借口or抽象类,具体的对象是什么?
4 实例化(第三部分)都坐了那些操作
ProcessState
单例模式,并且在构造函数中打开了Binder设备,也就是说:
1)每个进程中只有一个ProcessState对象
2)只打开了一次Binder设备
defaultServiceManager()的返回
启动过程中的第二部分,获取一个IServiceManager对象,
defaultServiceManager();
{
……
return interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));}
//ProcessState::self()->getContextObject(NULL)
sp<IBinder>ProcessState::getContextObject(const sp<IBinder>& caller)
{
……
return getStrongProxyForHandle(0);
}
//getStrongProxyForHandle(0);
sp<Ibinder>ProcessState::getStrongProxyForHandle( inte32_t handler)
{……、
return new BpBinder(handle);
}
从上面的代码看到两类Binder和IServiceManager,这是两个大的“家族”。
Binder家族
BpBinder—Client端的对象
BBinder—Server端的对象
BpBinder和BBinder是一一对应的
Server家族
Binder机制里每个Server都要符合这样的家族“族谱”:
其中的XXX就指具体的服务,在Binder中ServiceManager也是个Server,应该有自己的有IserviceManager;{defaultServiceManager所获取的那个对象}
再返回代码defaultServiceManager代码中,由interface_cast的实现可以发现,IServiceManager通过宏定义实现了一个BpServiceManager;
return interface_cast<IServiceManager>
(ProcessState::self()->getContextObject(NULL))
#define IMPLEMENT_META_INTERFACE(INTERFACE,NAME)
……
if (intr == NULL) {
intr = newBp##INTERFACE(obj);
}
其中INTERFACE就是每个Server的名称,在此处为ServiceManager,会生返回一个BpServiceManager对象。
IServiceManager的方法:
virtual sp<IBinder> getService(constString16& name)
获取一个Service
virtual sp<IBinder> checkService(const String16& name)
检查一个Service
virtual status_t addService(constString16& name, const sp<IBinder>& service)
想ServiceManager中添加一个Service
virtual Vector<String16>listServices()
获取ServiceManager管理的所有可用的Service
第三步:instantiate/实例化
以MediaPlayerService为例:
defaultServiceManager()->addService(String16(“media.player”),newMediaPlayerService());
只有一句话,想Servicemanager中添加一个Service,具体的添加实现会调用到
BpBinder()->transact();而该方法最终会执行下面的代码IPCThreadState()->transact();
再看IPCThreadState:
特点:每个线程有一个;Service支持多线程;
功能:transact();handle,发送,循环等待;
重点:talkWithDriver();
Ipcthreadstate的transact方法是一个发送和循环等待的逻辑,也就是实际的交互逻辑;
最终的交互方法是talkWithDriver(),与BinderDriver交互,获取和写入数据。
最后两步骤:
4) ProcessState::self()->startThreadPool();
开启线程池,将每个线程的IPCThreadState对象都调用一下joinThreadPool();
5) IPCThreadState::self()->joinThreadPool();
本身也调用一下joinThreadPool()——>talkWithDriver();
joinThreadPool最终也会talkWithDriver,等待Driver给自己消息,然后提供服务。
ServiceManager.c
ServiceManager在binder 架构中提供管理Server的服务,也是一个Server,前面可见其有IServiceManager和bpServiceManager,应该有对应的bnserviceManager 但是巡边源码都找不到;
确实有代码实现了bnServiceManager应该实现的服务,也就在上页中介绍的内容,在service_manager.c文件中,实现了bnServiceManager的功能。
//ServiceManager的启动过程
intmain(int argc, char **argv) {
structbinder_state *bs;
void*svcmgr = BINDER_SERVICE_MANAGER;
bs =binder_open(128 * 1024);
if(binder_become_context_manager(bs)) {
LOGE("cannotbecome context manager (%s)\n", strerror(errno));
return-1;
}
svcmgr_handle= svcmgr;
binder_loop(bs,svcmgr_handler);
return0;
}
Svcmgr_handler是个函数指针,其具体实现了addservice,checkservice,getservice,listservices。
两个疑点解惑:
BBinder:Server的实现确实需要遵循Server大家族结构,以F热管Service为例:FregService—>BnFregService->BnInterface->BBinder,其中的à表示继承关系。
确实没有BnServiceManager。
没有涉及到的:
open/ioctl
servicemanager提供的其他服务
实现一个服务native、aidl(AndroidInterface definition language)
Binder是什么?
Binder是Android进程间通信机制,就像共享内存,共享文件等一样,是一套IPC的机制;
Android的Binder机制是在OpenBinder开源项目实现的;
Binder机制是一个C/S的通信架构
相比于其他IPC的优势?
更好的传输性能
SOCKET:是一个通用接口,导致其传输效率低,开销大;
管道和消息队列:因为采用存储转发方式,所以至少需要拷贝2次数据,效率低;
共享内存:虽然在传输时没有拷贝数据,但其控制机制复杂;
更高的安全性
Binder机制的UID/PID是由Binder机制本身在内核空间添加身份标识,安全性高;
Binder可以建立私有通道,这是linux的通信机制所无法实现的;
Binder的整体架构:
从图中我们可以看出:
1)IPC指的是Client和Server模块之间的通信,虚线的双向箭头表示实际的数据并非Client、Server间直接传递,而是通过实线箭头传递的;
2)Client通过open、ioctl两个方法将自己需要通信的数据传入底层BinderDriver中,Server端通过open和ioctl获取Client写入BinderDriver中的数据,然后处理并再次通过Driver返回给Client;
3)ServiceManager,Binder中的老大,不负责具体通信工作,负责管理Server;
4)Binder机制实际上是虚拟了一个Binder设备,放在/dev/目录下,Client和Server通过访问BinderDriver实现互相之间的通信。
图中所能看到的问题:
1) Service Manager有什么用?
Binder通信中的老大,管理Server,系统中每个进程(Client和Server)都知道ServiceManager的位置,Server要提供服务,需要在ServiceManager中注册,Client需要什么服务需要向ServeiceManager要,这样Client和Server两端才能取得联系,互相通信;
2)Client/Server之间怎么通信的?
接下来通过一个MediaPlayerService的启动过程分析;
3)open/ioctl 做了什么?
open和ioctl是Linux驱动编程的方法,用来访问驱动程序
Client/Server之间怎么通信的?
通过MediaPlayerService的启动过程来分析Client和Server之间是怎么通信的;
// MediaPlayService 启动main函数
int main(int argc, char** argv) {
1) sp<ProcessState>proc(ProcessState::self());
2)sp<IServiceManager>sm = defaultServiceManager();
3) AudioFlinger::instantiate(); MediaPlayService::instantiate();CameraService::instantiate(); AudioPolicyService::instantiate();
4)ProcessState::self()->startThreadPool();
5)IPCThreadState::self()->joinThreadPool();
}
整个的启动分为5个部分
1 实例化一个ProcessState
2 获取一个IServiceManager对象
3 各种实例化
4 开启一个线程池
5 当前线程调用一个joinThreadPool()方法
新的问题:
1 ProcessState有什么作用?
2 IPCThreadState有什么作用?
3 IserviceManager明显是个借口or抽象类,具体的对象是什么?
4 实例化(第三部分)都坐了那些操作
ProcessState
单例模式,并且在构造函数中打开了Binder设备,也就是说:
1)每个进程中只有一个ProcessState对象
2)只打开了一次Binder设备
defaultServiceManager()的返回
启动过程中的第二部分,获取一个IServiceManager对象,
defaultServiceManager();
{
……
return interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));}
//ProcessState::self()->getContextObject(NULL)
sp<IBinder>ProcessState::getContextObject(const sp<IBinder>& caller)
{
……
return getStrongProxyForHandle(0);
}
//getStrongProxyForHandle(0);
sp<Ibinder>ProcessState::getStrongProxyForHandle( inte32_t handler)
{……、
return new BpBinder(handle);
}
从上面的代码看到两类Binder和IServiceManager,这是两个大的“家族”。
Binder家族
BpBinder—Client端的对象
BBinder—Server端的对象
BpBinder和BBinder是一一对应的
Server家族
Binder机制里每个Server都要符合这样的家族“族谱”:
其中的XXX就指具体的服务,在Binder中ServiceManager也是个Server,应该有自己的有IserviceManager;{defaultServiceManager所获取的那个对象}
再返回代码defaultServiceManager代码中,由interface_cast的实现可以发现,IServiceManager通过宏定义实现了一个BpServiceManager;
return interface_cast<IServiceManager>
(ProcessState::self()->getContextObject(NULL))
#define IMPLEMENT_META_INTERFACE(INTERFACE,NAME)
……
if (intr == NULL) {
intr = newBp##INTERFACE(obj);
}
其中INTERFACE就是每个Server的名称,在此处为ServiceManager,会生返回一个BpServiceManager对象。
IServiceManager的方法:
virtual sp<IBinder> getService(constString16& name)
获取一个Service
virtual sp<IBinder> checkService(const String16& name)
检查一个Service
virtual status_t addService(constString16& name, const sp<IBinder>& service)
想ServiceManager中添加一个Service
virtual Vector<String16>listServices()
获取ServiceManager管理的所有可用的Service
第三步:instantiate/实例化
以MediaPlayerService为例:
defaultServiceManager()->addService(String16(“media.player”),newMediaPlayerService());
只有一句话,想Servicemanager中添加一个Service,具体的添加实现会调用到
BpBinder()->transact();而该方法最终会执行下面的代码IPCThreadState()->transact();
再看IPCThreadState:
特点:每个线程有一个;Service支持多线程;
功能:transact();handle,发送,循环等待;
重点:talkWithDriver();
Ipcthreadstate的transact方法是一个发送和循环等待的逻辑,也就是实际的交互逻辑;
最终的交互方法是talkWithDriver(),与BinderDriver交互,获取和写入数据。
最后两步骤:
4) ProcessState::self()->startThreadPool();
开启线程池,将每个线程的IPCThreadState对象都调用一下joinThreadPool();
5) IPCThreadState::self()->joinThreadPool();
本身也调用一下joinThreadPool()——>talkWithDriver();
joinThreadPool最终也会talkWithDriver,等待Driver给自己消息,然后提供服务。
ServiceManager.c
ServiceManager在binder 架构中提供管理Server的服务,也是一个Server,前面可见其有IServiceManager和bpServiceManager,应该有对应的bnserviceManager 但是巡边源码都找不到;
确实有代码实现了bnServiceManager应该实现的服务,也就在上页中介绍的内容,在service_manager.c文件中,实现了bnServiceManager的功能。
//ServiceManager的启动过程
intmain(int argc, char **argv) {
structbinder_state *bs;
void*svcmgr = BINDER_SERVICE_MANAGER;
bs =binder_open(128 * 1024);
if(binder_become_context_manager(bs)) {
LOGE("cannotbecome context manager (%s)\n", strerror(errno));
return-1;
}
svcmgr_handle= svcmgr;
binder_loop(bs,svcmgr_handler);
return0;
}
Svcmgr_handler是个函数指针,其具体实现了addservice,checkservice,getservice,listservices。
两个疑点解惑:
BBinder:Server的实现确实需要遵循Server大家族结构,以F热管Service为例:FregService—>BnFregService->BnInterface->BBinder,其中的à表示继承关系。
确实没有BnServiceManager。
没有涉及到的:
open/ioctl
servicemanager提供的其他服务
实现一个服务native、aidl(AndroidInterface definition language)
相关文章推荐
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路(1)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(3)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路(2)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(2)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(4)
- IPC(进程间通信),Remote Call(远程调用),IDL(接口描述语言)架构及其在BMP(BREW移动平台),Android中的应用浅析
- Android进程间通信--消息机制及IPC机制实现
- Android进程间通信(IPC)机制Binder简要介绍和学习计划
- Android进程间通信(IPC)机制Binder简要介绍和学习计划
- Android 进程间通信
- Android进程间通信--消息机制及IPC机制实现 推荐
- android进程间通信:使用AIDL
- 理解Android系统的进程间通信原理(一)----RPC中的-代理模式 -RMI-RPC
- 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(2)
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析