首先看看Binder的详细介绍;https://blog.csdn.net/coding_glacier/article/details/7520199
大半年前第一次看,基本上看不懂,只是大致有一些印象:Bp,Bn,ServiceManager...
image.pngimage.png
- Java应用层: 对于上层应用通过调用AMP.startService, 完全可以不用关心底层,经过层层调用,最终必然会调用到AMS.startService.
- Java IPC层: Binder通信是采用C/S架构, Android系统的基础架构便已设计好Binder在Java framework层的Binder客户类BinderProxy和服务类Binder;
- Native IPC层: 对于Native层,如果需要直接使用Binder(比如media相关), 则可以直接使用BpBinder和BBinder(当然这里还有JavaBBinder)即可, 对于上一层Java IPC的通信也是基于这个层面.
-
Kernel物理层: 这里是Binder Driver, 前面3层都跑在用户空间,对于用户空间的内存资源是不共享的,每个Android的进程只能运行在自己进程所拥有的虚拟地址空间, 而内核空间却是可共享的. 真正通信的核心环节还是在Binder Driver.
image.png
从AudioSystem--IAudioPolicyService--AudioPolicyService一路来看.
AudioSystem::getOutPut()函数里创建了一个IAudioPolicyService对象:
audio_io_handle_t AudioSystem::getOutput(省略)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
}
按照通常定义的理解 I某某 都是 某某的Bp端.
const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service()
{
省略
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.audio_policy"));//在AudioPolicyService.h文件里,static const char *getServiceName() ANDROID_API { return "media.audio_policy"; }
/*
以下内容对应c语言里
1.初始化binder,打开/dev/binder设备;在内存中为binder映射128K字节空间;
2.指定SM对应的代理binder的handle为0,当client尝试与SM通信时,需要创建一个handle为0的代理binder,这里的代理binder其实就是Bp;
3.通知binder driver(BD)使SM成为BD的context manager;
4.维护一个死循环,在这个死循环中,不停地去读内核中binder driver,查看是否有可读的内容;即是否有对service的操作要求, 如果有,则调用svcmgr_handler回调来处理请求的操作。
5.SM维护了一个svclist列表来存储service的信息。
*/
if (binder != 0)
break;
ALOGW("AudioPolicyService not published, waiting...");
usleep(500000); // 0.5 s
} while (true);
...
// Make sure callbacks can be received by gAudioPolicyServiceClient
// Pool thread的启动:
ProcessState::self()->startThreadPool();
/*
Pool thread的实际内容则为:
IPCThreadState::self()->joinThreadPool();
IPCThreadState也是以单例模式设计的。由于每个进程只维护了一个ProcessState实例,同时ProcessState只启动一个Pool thread.
ProcessState中有2个Parcel成员,mIn和mOut,Pool thread会不停的查询BD中是否有数据可读,如果有将其读出并保存到mIn,同时不停的检查mOut是否有数据需要向BD发送,如果有,则将其内容写入到BD中,总而言之,从BD中读出的数据保存到mIn,待写入到BD中的数据保存在了mOut中。
ProcessState中生成的BpBinder实例通过调用IPCThreadState的transact函数来向mOut中写入数据,这样的话这个binder IPC过程的client端的调用请求的发送过程就明了了。
BpBinder的transact方法是向IPCThreadState实例发送消息,通知其有消息要发送给BD
而BBinder则是当IPCThreadState实例收到BD消息时,通过BBinder的transact的方法将其传递给它的子类BnSERVICE的onTransact函数执行server端的操作。
*/
}
ap = gAudioPolicyService;
}
return ap;
}
image.png
以上是client端获取Bp端;接下来是Bn端找server的此方法.先是去AudioPolicyService里找AudioPolicyInterfaceImpl,它的实现类,AudioPolicyService里面有很多方法是放在了 AudioPolicyInterfaceImpl.cpp 去实现的.
status_t AudioPolicyService::getOutputForAttr(...){
...
//完成client所要求的任务,将
status_t结果返回给client
}
'''
从读代码的角度看了一遍下来,理解一下Binder,然后再对照着开篇的链接去理解Binder会有新的感受
网友评论