我们要知道,Android系统基本上可以看做是一个基于Binder通信的C/S架构,Binder把Android系统的各个部分都连在了一起,所以它的重要不可言喻,我们有必要掌握好它。
Binder是Android系统提供的一种 “ 进程间通信(IPC)” 机制。在基于Binder的C/S**(Client、Service)架构中除了 **Client和Service端外、Android还有一个ServiceManager,它管理系统中的各种服务。
由上图可知:
- Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端.
- 如果某个Client进程要使用Server,则必须先去ServiceManager去查询服务,所以Client是ServiceManager的客户端
- Client根据得到的Service信息与Service所载的Server进程建立通信线路,然后就可以和Service交互了,所以Client是Service的客户端
我们要分析Binder,必然要以一个入口来分析它,由于我没有自行分析过C层代码,所以就按照我所学的来,用MediaServer来打开我们的Binder之路。
以下代码使用在线阅读网站:http://androidxref.com/进行阅读,且代码版本为 7.1.1_r6
MediaServer(main_mediaserver.cpp)
源码位置:
1. 4.0.x版本路径
2. 4.0.x以上版本
Notice:以下代码省略了大部分与分析无关的代码。
分析:
进入main_dediaserver.cpp中我们可以看见,内部只有一个main方法
int main(int argc __unused, char **argv __unused){
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
MediaPlayerService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
上面操作总共分为5部分。
1. 获得一个ProcessState实例
2. 获取一个IServiceManager
3. 多媒体系统MediaPlayer服务
4. 创建线程池
5. 将自己加入线程池中
由上面5部分我们进行代码分析..
ProcessState::self
ProcessState::self()
进入ProcessState的self方法 ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
看上面代码得知,如果gProcess不等于null,那么直接返回。 否则新建一个ProcessState 并赋值给gProcess 然后返回。由代码可知,self采用了单例模式,说明了每个进程中只能有一个ProcessState。 下面进入ProcessState构造
ProcessState::ProcessState()
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
.......
......
{
if (mDriverFD >= 0) {
mVMStart=mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
close(mDriverFD);
mDriverFD = -1;
}
}
}
在上面代码中,我们看open_driver()
open_driver():该函数的作用是 用来打开/dev/binder 这个设备,它是Android在内核中用来完成进程间通信的一个虚拟设备.
mmap():BINDER_VM_SIZE =(1*1024*1024) -(4096*2) =1M-8k,该函数实现后,binder驱动会分配一块内存区域来接收数据
static int open_driver(){
int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
if (fd >= 0) {
....
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
....
}
return fd;
}
上面代码做了2件事
1. 打开binder设备
2. 通过ioctl的方式告诉binder驱动,该fd最大支持线程数
所以由ProcessState::self可知:
- ProcessState进程唯一
- 打开了/dev/binder 虚拟设备
- 打开后使用mmap,Binder驱动会分配一块内存接收数据
defaultServiceManager
defaultServiceManager返回的是一个IServiceManager对象,通过它我们可以与别的进程的ServiceManager进行交互。
下面分析代码 IServiceManager.cpp
sp<IServiceManager> defaultServiceManager(){
if (gDefaultServiceManager != NULL)
return gDefaultServiceManager;
{
...
while (gDefaultServiceManager == NULL) { gDefaultServiceManager=interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
看代码可知,是个单例,接着调用了3个方法来获取gDefaultServiceManager.
1. 先获取ProcessState实例
2. 调用ProcessState的getContextObject函数,注意参数为NULL
3. 把getContextObject返回的变量作为interface_case参数调用
首先来看getContextObject ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(constsp<IBinder>& caller){
return getStrongProxyForHandle(0);
}
可以看到这里直接调用了getStrongProxyForHandle(0).. 注意传入的是个0..并返回了IBinder…
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
.....
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
}
return result;
}
- lockupHandleLocked:该函数参数handle代表的意义为索引,根据索引去一个资源数组里面去寻找资源,如果没有则创建一个新的项并返回。
- 对于新创建的资源, binder为null,所以进入分支,然后创建BpBinder,并赋值handle_entry 的binder, 最后赋值给result.
- 返回BpBinder(handle), handle的值为0.
BpBinder是什么?
IPC内重要部分其中就是BpBinder,实现了IBinder类。
IBinder 有两个实现类,分别是 BpBinder、BBinder。
- BpBinder是客户端用来与服务端交互的代理类,p 译为proxy
BBinder则是服务端.
BpBinder 与BBinder是一一对应的。
BpBinder::BpBinder(int32_t handle) : mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(NULL){ extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle); }
由上面代码我们看到了一个IPCThreadState,它是什么?
现在我们知道了getContextObject() 实际染回的是一个BpBinder(0)对象,那么代码就变成了interface_cast(new BpBinder(0));
interface_cast是什么? 我们可以在IInterface.h内查看它的定义.
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){
return INTERFACE::asInterface(obj);
}
可以看到这相当于一个模版,根据传进来的泛型来调用泛型类所对应的方法,那么我们可以接着看IServiceManager::asInterface(new BpBinder(0)).
我们想象一下,BpBinder和BBinder是用于通信的,那么如何和这些东西关联上?答案就是通过IServiceManager,下面看IServiceManager的定义
IServiceManager.h
class IServiceManager : public IInterface
{
public:DECLARE_META_INTERFACE(ServiceManager);
....
virtual sp<IBinder> getService( const String16& name) const = 0;
virtual sp<IBinder> checkService( const String16& name) const = 0;
virtual status_t addService( const String16& name,
const sp<IBinder>& service, bool allowIsolated = false) = 0;
virtual Vector<String16> listServices() = 0;
.....
};
需要注意的是 DECLARE_META_INTERFACE(ServiceManager),其余则是提供给ServiceManager的一些方法.
前面说到过,如何与BpBinder和BBinder关联上? 实际则是通过DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE 这两个宏来关联的。它们两个的定义在IInterface.h中。
#define DECLARE_META_INTERFACE(INTERFACE)
static const android::String16 descriptor;
static android::sp<I##INTERFACE> asInterface(const android::sp<android::IBinder>& obj);
virtual const android::String16&getInterfaceDescriptor() const;
I##INTERFACE();
virtual ~I##INTERFACE();
DECLARE_META_INTERFACE(ServiceManager) 把ServiceManager替换得到下面这样。
static const android::String16 descriptor;
static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
IServiceManager();
virtual ~IServiceManager();
由名字可知,DECLARE 为定义,那么IMPLEMENT肯定为实现了。原始宏就不贴代码了,跟上面一个套路。我们来看看它的实际使用。
IServiceManager.cpp
IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");
它在IServiceManager.cpp 中的最后一行代码,经过Interface.h宏定义的模版转换后,那么就变成下面的样子
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
const android::String16 IServiceManager::descriptor("android.os.IServiceManager");
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
android::sp<IServiceManager> IServiceManager::asInterface(
const android::sp<android::IBinder>& obj)
{
android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
现在我们知道了,interface_cast 《IServiceManager》(new BpBinder(0)),最后是调用了 IServiceManager::asInterface(new BpBinder(0)),最后把BpBinder(0)作为参数 来创建BpServiceManager。
BpServiceManager是什么?要明白这个问题,我们先来了解一下IServiceManager相关类的关系。
在BpServiceManager的构造内 会调用BpInterface构造,并把参数传递,最后会赋值给BpRefBase的 mRemote, 到这,就和BpBinder联系上了。
到这里 defaultServiceManager分析完成,它主要完成了以下工作。
- 创建了一个BpBinder对象,handle值为0
- 创建了一个BpServiceManager 并把 BpBinder赋值给mRemote
知道了通信层是如何工作的,那么业务层是怎样的?我们通过MediaPlayerService来分析一下。
MediaPlayerService::instantiate();
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
defaultServiceManager 返回BpManagerService.
virtual status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated){
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
status_t err=remote()>transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
把Parcel数据包打包 并传给BpBinder的transact函数.
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
可以看到,实际上BpBinder只是个工具!!! 实际操作的是IPCThreadState。
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {
restart:
const pthread_key_t k = gTLS;
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
return new IPCThreadState;
}
goto restart;
}
gTLS: TLS为(Thread Local Storage)简称,为线程本地存储空间,每个线程都有一个,pthread_getspecific 从TLS内获取IPCThreadState,如果有就返回,没有就创建一个。
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mMyThreadId(gettid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
pthread_setspecific(gTLS, this);
clearCaller();
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
IPCThreadState构造内调用pthread_setspecific 把自己设置进去,并设置mIn,mOut缓冲区(两个Parcel) 用来接收和发送数据。
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck();
....
if (err == NO_ERROR) {
...
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
...
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
.....
return err;
}
BC_TRANSACTION 是应用程序向Binder设备发送消息的消息码,binder设备回复信息以BR_开头。
5status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.ptr = 0;
//handle为0,表示目的端ServiceManager
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
.....
.....
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
最后把命令写到mOut中,接下来走writeForResponse
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_t cmd;
int32_t err;
while (1) {
//注意talkWithDriver
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = (uint32_t)mIn.readInt32();
switch(cmd){
.....
default:
err = executeCommand(cmd);
break;
}
....
return err;
假设我们发送后,马上得到了回复,然后我们看executeCommand(cmd),其内根据一些binder设备 返回的 以BR开头的码来做不同的事情。
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
....
case BR_TRANSACTION:
{
....
....
if (tr.target.ptr) {
....
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
....
}
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
}
break;
上面把tr.cookie转成了BBinder,它的实际对象是BnServiceManager,我们来看BBinder的transaction.
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
这里的onTransact函数会调用到BBinder子类的onTransact,然后子类进行处理。可以在这里 查看onTransact函数,知道这一处,别的都一样。
发送请求是在talkWithDriver内,这里就不贴代码了。其内主要是用ioctl方式来发送请求。到这为止,发送与接收就告一段落了继续分析下面。
startThreadPool
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
//如果已经 startThreadPool过,则略过
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);// 这里为true
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
PoolThread是ProcessState内 Thread的一个子类
class PoolThread : public Thread
{
public:
PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
接着调用了IPCThreadState的joinThreadPool方法.
void IPCThreadState::joinThreadPool(bool isMain)
{
//如果为true 则循环处理,把信息写到mOut内
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
set_sched_policy(mMyThreadId, SP_FOREGROUND);
status_t result;
do {
//处理已经死亡的BBinder
processPendingDerefs();
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
.....
mProcess->mDriverFD, result);
abort();
}
if(result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
(void*)pthread_self(), getpid(), (void*)result);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
在getAndExecuteCommand内 又调用了talkWithDriver 发送请求给binder,和executeCommand 接收回复的方法。
所以由以上代码可知,主线程,和startThreadPool的线程 分别在读取binder设备,查看是否有请求。
到这里,我们应该大体明白了Binder的流程。
1. 创建BpBinder(0)
2. 创建BpServiceManager(BpBinder(0)),在BpServiceManager内,把BpBinder赋值给了mRemote,至此业务层关联了BpBinder
3. 注册服务,调用BpServiceManager的addService函数,在其内调用 BpBinder的transact.
4. 创建IPCThreadState并调用 它的transact,传入的参数mHandler为0,用户标示目的地的服务端(ServiceManager).
5. 在transact内的waitForResponse内 while(1){来发送,等待接收binder消息}
6. 在while(1){}内 的executeCommand内的 case BR_TRANSACTION:内 获取了BBinder 然后调用其 transact.
7. BBinder 的transact调用了子类的 onTransact函数.
至此消息发送到了服务端的onTransact函数,完成了进程间通信(IPC)
疑问 , 谁是BBinder的子类 用来接收onTransact函数。?
答案是ServiceManager来做这些工作的。
可以说,如果想要进程间通信,则必须向ServiceManager注册服务,然后客户端通过向ServiceManager查询 获取到的Server 来进行响应处理。
有关于ServiceManager从onTransact接收后 如何处理,请大家自定去分析~~~链接上面已给。