Android Binder机制浅析(一)
来源:互联网 发布:客户管理系统源码 编辑:程序博客网 时间:2024/05/29 17:59
Binder是Android系统进程间通信(IPC)方式之一。Linux已经拥有的进程间通信IPC手段包括(Internet Process Connection): 管道(Pipe)、信号(Signal)和跟踪(Trace)、插口(Socket)、报文队列(Message)、共享内存(Share Memory)和信号量(Semaphore)。本文分析的是Binder的实现以及Binder组件Client、Server和Service Manager、Binder驱动的相互关系
本文根据网上现有资源进行整合,以及自己的理解,有误之处欢迎指正~~
一、概述
Android 系统 Binder机制中有四个组件Client、Service、Service Manager和Binder驱动程序,大致模型如下
1. Client、Server和Service Manager实现在用户空间中,Binder驱动程序实现在内核空间中
2. Binder驱动程序和Service Manager在Android平台中已经实现,开发者只需要在用户空间实现自己的Client和Server
3. Binder驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和Service Manager通过open和ioctl文件操作函数与Binder驱动程序进行通信
4. Client和Server之间的进程间通信通过Binder驱动程序间接实现
5. Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力
本文以MediaServer为例,学习Binderd机制
ServiceManager: Android 整个服务的管理程序
MediaService: 在此程序里注册提供媒体播放的服务程序MediaPlayerService
MediaPlayerClient 与MediaPlayerService交互的客户端程序
二、MediaService
源码目录在frameworks/av/media/mediaserver/main_mediaserver.cpp
Main ()
signal(SIGPIPE, SIG_IGN);
>> sp<ProcessState> proc(ProcessState::self());
>> sp<IServiceManager> sm(defaultServiceManager()); ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
>> MediaPlayerService::instantiate(); //初始化MediaService 服务
......
ProcessState::self()->startThreadPool(); // 启动线程池IPCThreadState::self()->joinThreadPool();
2.1 ProcessState 类
调用ProcessState::self() ,然后赋值给proc变量,程序运行结束后,proc会自动delete内部内容,会自动释放先前分配的资源
目录在 frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
>> gProcess = new ProcessState;
return gProcess;
//将由2.2中 gDefaultManagergetContextObject函数传递
}
追到ProcessState构造函数
ProcessState::ProcessState()
>> : mDriverFD(open_driver())
>> , mVMStart(MAP_FAILED) //映射内存起始地址
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
...
...
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
//将fd映射为内存,这样内存的mmcpy 等操作就相当于write/read了
if (mVMStart == MAP_FAILED) {
// *sigh*
ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD = -1;
}
}
open_driver(),打开/dev/binder设备,是Android 在内核中设置的一个用于完成进程间通信的虚拟设备,追代码
static int open_driver()
{
int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
if (fd >= 0) {
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
...
...
...
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;//最大支持线程数15个
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
...
...
...
return fd;
}
小结:ProcessState::self()作用
1. 打开/dev/binder设备,相当于和内核binder机制有了交互通道
2. 将fd映射到内存,设备fd传入后,内存将于binder设备共享
接着分析defaultServiceManager
2.2 defaultServiceManager
源码目录在 frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
// 单例设计模式
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
//创建gDefaultServiceManager
>> gDefaultServiceManager = interface_cast<IServiceManager>(
>> ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
其中,ProcessState::self()返回的是刚才创建的gProcess,然后调用getContextObject(),传参为NULL,即0
追getContextObject代码
目录在 frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
追getStrongProxyForHandle
//handle 是windows一种资源的标示 比如某个数据结构,保存在数组中,handle是它在数组中的索引
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle); //从数组中查找对应索引的资源
....
...
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b; //返回创建的BpBinder
...
}
我们从
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));追代码
现在函数调用为
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0))
2.3 BpBinder
目录 frameworks/native/libs/binder/BpBinder.cpp
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)//从上述传递为0
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
{
...
IPCThreadState::self()->incWeakHandle(handle);
}
在此,先追一下IPCThreadState()
目录在 frameworks/native/libs/binder/IPCThreadState.cpp
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {//第一次进为false
restart:
const pthread_key_t k = gTLS;
//TLS 是Thread Local Storage 线程本地存储空间,每个线程都会有,但线程间不 会共享这些空间,可以不用再设置同步
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
//pthread_getspecific 获取保存在TLS中的IPCThreadState对象
//在其他地方有调用
if (st) return st;
return new IPCThreadState;
}
...
pthread_mutex_lock(&gTLSMutex);
...
...
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
追查pthread_getspecific函数,可得在
IPCThreadState构造函数里有个pthread_setspecific
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mMyThreadId(gettid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
pthread_setspecific(gTLS, this);
clearCaller();
//min、mout是两个Parcel,读取数据的容器
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
至此,再调用incWeakHandle(),handle为0
小结:
gDefaultServiceManager创建了
ProcessState、IPCThreadState(主线程中)、BpBinder(内部handle为0)
再次回到2.2最后的函数
>> gDefaultServiceManager=interface_cast<IServiceManager>(new BpBinder(0))
BpBinder分析之后,发现BpBinder* 指针如何转换为IServiceManager*,
由此关注interface_cast
回到2.2中的frameworks/native/libs/binder/IServiceManager.cpp
点击interface_cast,跳转至
frameworks/native/include/binder/IInterface.h
发现
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
} 即,等价于
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
于是,再次追IServiceManager,如何实现
2.4 IServiceManager
目录在 frameworks/native/include/binder/IServiceManager.h
//Service 管理类,管理增加服务、查询服务等
class IServiceManager : public IInterface
{
public:
DECLARE_META_INTERFACE(ServiceManager);//类似MFC
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;
...
}
...
回到frameworks/native/include/binder/IInterface.h
DECLARE_META_INTERFACE
#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; \
//增加get函数,返回值即为descriptor字符串
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
IMPLEMENT_META_INTERFACE
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
>> return I##INTERFACE::descriptor;
//返回上面android.os.IServerManager \
} \
>> android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { }
两个宏分别兑现之后
NAME等价于android.os.IServerManager
##INTERFACE等价于IServiceManager
上面提到的 interface_cast<IServiceManager>(new BpBinder(0))就是调用
asInterface(new BpBinder(0))
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; \
}
在这里,返回的intr= BpServiceManager(new BpBinder(0));
2.5 BpServiceManager
目录在 frameworks/native/libs/binder/IServiceManager.cpp
Bp 是Binder proxy,BpServiceManager是ServiceManager的Binder代理,
class BpServiceManager : public BpInterface<IServiceManager>
{
>>// 这种继承方式,标示同时继承BpInterface和IServiceManager,故IServiceManager的addService在这个类中实现
public:
//impl?好像是Bridge模式,impl对象??
// 传参的impl就是之前的new BpBinder(0)
BpServiceManager(const sp<IBinder>& impl)
: BpInterface<IServiceManager>(impl)
{
}
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
...
}
这里先追BpInterface,将INTERFACE兑现为IServiceManager
inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
// remote传参
{
}
BpRefBase::BpRefBase(const sp<IBinder>& o)
: mRemote(o.get()), mRefs(NULL), mState(0)
//o.get() 是sp类的获取实际数据指针的一个方法,
// 它返回的是sp<xxx>中的xxx*指针
//mRemote是刚才传入的BpBinder(0)
{
...
}
}
至此,重新回到在第二章开始处 MediaServer的main中的
sp<IServiceManager> sm (defaultServiceManager());
返回的实际是BpServiceManager它的remote对象是BpBinder,传入的handle参数是0
同时,binder设备已经打开,得到一个BpServiceManager对象,
表示可以和ServiceManager打交道
接下来就是MediaPlayerService::instantiate() 实例化服务
- Android Binder机制浅析(一)
- 浅析Android binder机制
- Android Binder机制浅析
- 浅析Android binder机制
- Android Binder机制浅析
- 浅析Android binder机制
- Android Binder机制浅析
- Android Binder机制浅析
- Android Binder机制浅析
- Android Binder机制浅析
- Android的Binder机制浅析
- Android的Binder机制浅析
- Android的Binder机制浅析
- Android的Binder机制浅析
- Android Binder通信机制浅析
- Android Binder机制浅析(二)
- Android Binder机制浅析(三)
- 【Android进阶】浅析Android Binder机制
- 【后台】菜单管理界面菜单项增加自定义字段
- Struts2 方法动态调用,验证表签,xml配置Action
- hdu 6140
- 51 nod 1435 位数阶乘
- 剑指Offer_面试题33_把数组排成最小的数
- Android Binder机制浅析(一)
- 8.17--练习赛B题--River Hopscotch(二分)
- ARM学习笔记三
- IO流
- Python3爬虫代理服务器与cookie的使用
- 几种web服务器端推送技术的简单介绍
- 半平面交
- SQL的多表查询和子查询
- java代码优化