IPC analysis on android with a demo (基于IPC实例分析android IPC机制)
The communication between the Client side and the server side is through Binder. Binder comm-unication is implemented via binder driver of Linux. Binder communicating operation look like thread migrat
IPC ANALYSIS ON ANDROID
TABLE OF CONTENTS
The communication between the Client side and the server side is through Binder. Binder comm-unication is implemented via binder driver of Linux. Binder communicating operation look like thread migration, IPC between two process look like A process come in B process and return back the result. Communication is synchronization not asynchronism.
This document will analysis the mechanism of IPC.You will understand the binder more and you can implement your IPC code by referencing to the example of IPCdemo.
The IPCdemo code that you can get from me,you can send email to me.
List all abbreviations and professional glossary which are understood difficulty here, and explain them in detailed. The table as follows:
Abbreviations and acronyms | Explanation |
IPC | Inter-Process Communication |
Binder | The base of Android Inter-Process Communication |
kernel/ include/linux/binder.h
kernel/drivers/android/binder.c
frameworks/base/cmds/servicemanager/binder.h
frameworks/base/cmds/servicemanager/binder.c
frameworks/base/cmds/servicemanager/service_manager.c
frameworks/base/include/utils/IInterface.h
frameworks/base/include/utils/Binder.h
frameworks/base/include/utils/BpBinder.h
frameworks/base/include/utils/IBinder
frameworks/base/include/utils/Parcel.h
frameworks/base/include/utils/IPCThreadState.h
frameworks/base/include/utils/ProcessState.h
frameworks/base/libs/utils/Binder.cpp
frameworks/base/libs/utils/BpBinder.cpp
frameworks/base/libs/utils/IInterface.cpp
frameworks/base/libs/utils/IPCThreadState.cpp
frameworks/base/libs/utils/Parcel.cpp
frameworks/base/libs/utils/ProcessState.cpp
The relation of classes in Binder is show in the figure 3-2
figure 3-1 relation of classes in Binder
RefBase.h :
reference count, define RefBase class.
Parcel.h :
define container for transfered data in IPC, define Parcel class
IBinder.h:
Abstract interface of Binder object, define IBinder class.
Binder.h:
Base function of Binder object, define Binder and BpRefBase class.
BpBinder.h:
function of BpBinder, define BpBinder class
IInterface.h:
define common class for abstract go through interface of Binder. Define IIterface class, class template BnInterface, class template BpInterface.
ProcessState.h
the class represent state of process, define ProcessState class.
IPCThreadState.h
this represent the state of thread, define IPCThreadState class.
The overall architecture of Android IPC system is shown in the picture.
Figure 3-2 overall architecture of Android IPC system
Binder Driver
It’s the core of IPC system. It transfers data between service provider and service user.
Service provider
It provides some kind of service. It will parser the received RPC call data from binder driver and do the real action.
Service_manager
It’s a special service provider. It provides service manager service for other service provider.
Service user
It remote calls service provider. It will generate an RPC call data and send it to binder driver.
Native part(Bn):
Implement BnABC:: BnTransact()
Register service:IServiceManager::AddService
Proxy(Bp):
Implement some function,transfer BpABC::remote()->transact()
Client: Get ABC interface, then transfer interface,(transfer BpABC in fact,then transfer BnABC via IPC, at last transfer the detail function)
Both BnABC and BpABC inherite interface ABC.
The main function of BpABC is communicate, it does not execute detail function; BnABC is a interface class, it needs a detail class to inherite and implement.
Communicate in BpABC and BnABC via IPC.
Next,let me show how the Android IPC system works
Figure 3-3 Android IPC system
Figure 4-1
JAVA: IPCdemo
Jni: native.cpp
MulProvider: MulProvider.h, MulProvider.cpp
IMul: IMul.h, IMul.cpp
Mul: Mul.h, Mul.cpp
MulService: MulService.cpp
service_manager provide service manager service to other process. It must be started before any other service gets running.
It first open “/dev/binder” driver and then call BINDER_SET_CONTEXT_MGR ioctl to let binder kernel driver know it acts as a manager. Then it enters into a loop to wait for any data from other process.
Pay attention to BINDER_SERVICE_MANAGER.
BINDER_SERVICE_MANAGER is the registered handle for service_manager. The other process must use this handle to talk with service_manager.
To get an IServiceManager instance the only method is to call defaultServiceManager implemented in IServiceManager.cpp.
gDefaultServiceManager is defined in libutil, so any program or library which included libutil will have this symbol, it’s unique in one process. The first time gDefaultServiceManager is NULL, so it will first get a ProcessState instance through ProcessState::self().One process has only one ProcessState instance. ProcessState will open “/dev/binder” driver for IPCThreadState use.
Now we have an instance of ProcessState, let’s look at the getContextObject.
The board support binder driver, so we will get into getStrongProxyForHandle. (Handle 0 is reserved for service manager, which will be explained later.)
The first time b will be NULL, so the code will new an BpBinder instance. BpBinder is a base proxy class for remote binder object.
IPCThreadState::incWeakHandle will add a BC_INCREFS command in output buffer.
Now getContextObject returns a BpBinder instance, it will be interface_cast to IServiceManager. interface_cast is defined in IInterface.h.
The code will be extended like this.
Now let’s take a look at definition of IServiceManager.
DECLARE_META_INTERFACE macro is defined as follows in IInterface.h. And it will be extended to the following code:
As you can see,DECLARE_META_INTERFACE macro declares two functions which are implement-ted by IMPLEMENT_META_INTERFACE macro in IServiceManager.cpp.
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
The code will be extended like this.
So IServiceManager::asInterface will finally new a BpServiceManager instance and return it to user. BpServiceManager works as a proxy for remote BnServiceManager. Any operation on IServiceManager now actually is to call the corresponding virtual functions in BpServiceManager.
Mul::instantiate()
首先defaultServiceManager() 是sp<IServiceManager> 而在IServiceManager 类定义中addService 成员函数只是虚函数声明了一下没有被定义,只有在BpServiceManager(继承IServiceManager) 类中才定义了addService函数,如下:
mServices is defined in ServiceManager.h
在MulProvider中我们可以看到MulProvider通过defaultServiceManager,即通过刚才的BpServiceManager得到我们在ServiceManager中注册的MULSERVICE服务.
binder=sm->getService(String16("MULSERVICE"))函数调用返回sp<IBinder>,然后通过itf=interface_cast <IMul>(binder),得到MULSERVICE的Bpmul,过程和刚才的/*函数调用4*/得到BpServiceManager一样,这里不再具体分析。
在IMul.h,我们定义了IMul类,该类继承自IInterface,还有BnMul类,该类继承自BnInterface。
/*函数调用9*/
remote()->transact(MUL_TRANSACTION, data, &reply);
remote()是BpRefBase 类的成员函数。 remote(); 实际调用Binder.h 中的
inline IBinder* remote() { return mRemote; }
remote()->transact(MUL_TRANSACTION, data, &reply)调用IBinder的成员函数transact,实际是调用BpBinder.cpp中的transact:
如下:
这个函数主要调用了IPCThreadState::self()->transact ,IPCThreadState::self 也使用自己的成员函数创建了一个类对象, 分析下IPCThreadState::self()->transact
BnMul以onTransact函数来解析BpMul 传过来对应的命令
Mul.cpp中的类Mul继承自BnMul,在该类中实现了具体的函数mul和getCall。
在Eclipse中建立android2.2工程,代码如下:
然后将程序下载到手机中,在adb shell 中启动mulservice,然后我们可以看到如下的效果
图5-1是IPC机制的流程图,图5-2是IPC调用的时序图,如果大家需要更加深入的了解IPC,可以阅读Binder的驱动程序部分。
图5-1 IPC机制流程图
图5-2 IPC调用时序图
我们得出:
如果一个服务需要通过binder机制对外提供跨进程的接口,需要做下面这些事情:
(1) 第一步,需要为这个接口定义一个继承自IInterface的接口类,假设叫做IMyService。
(2) 第二步,需要定义两个binder类,其中一个是代理类BpMyService,需继承自BpInterface;另一个是实现类BnMyService,需继承自BnInterface。
(3) 第三步,定义BnMyService的子类,这个子类可以是任何名字,比如就叫MyService,在其中真正实现接口所提供的各个函数。
(4) 第四步,创建MyService的实例,注册到服务管理器(如IMediaPlayerService),也可以在其它接口的函数中创建。
一篇android的IPC机制binder实例AudioFlinger国外文档
http://blog.chinaunix.net/u1/38994/showart_1676822.html
Android JAVA Binder IPC System
http://blog.chinaunix.net/u1/38994/showart_1680617.html
binder官网
http://blog.chinaunix.net/u1/38994/showart_1222450.html
Android IPC 通讯机制源码分析
http://hi.baidu.com/albertchen521/blog/item/30c32d3f4bee993a71cf6ca0.html
http://hi.baidu.com/albertchen521/blog/item/822058d0f63ea2d4562c84a1.html
Reference/android/app/Service
Android底层库libutils介绍
http://www.androidin.com/learn/cn/200901/22-437.html
Android 初学
http://www.fulema.com/forumdisplay.php?fid=4
大家会发现IServiceManager类和父类IInterface 找不到asInterface这个成员函数,这个函数实际上是通过上面的DECLARE_META_INTERFACE(ServiceManager); 这条语句来申明的,并且在IServiceManager.cpp 中使用IMPLEMENT_META_INTERFACE(Mul, "android.smrdn.IMul"); 定义了它们。
备注:整理于2010.12.07, 本篇博客百度文库: http://wenku.baidu.com/view/e9eb7c1efad6195f312ba61a.html
Email:safransx@gmail.com QQ: 1104472716
更多推荐
所有评论(0)