Android Binder

Posted by Young Ken on 2017-05-31

Binder 为什么出现?

binder 是Android系统进程的通讯方式。

Liunx IPC有system V IPC,socket等方式,但是因为socket因为效率低,开销大不。而System V IPC 会导全局的内核资源泄漏。还有一点就是出于安全考虑。

这个时候Binder就出现了,Binder采用的是Client-Server的通讯方式,一个进行作为Server提供服务(地址查询,网络连接),多个进程作为Client进行访问。

MediaServerd

因MediaServer包括AudioFinger,MediaPlayerService,CameraService等重要的服务,所有选择MediaServer为切入点。

MediaServer分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main(int argc, char** argv)
{
//①获得一个ProcessState实例
sp<ProcessState>proc(ProcessState::self());
//②MS作为ServiceManager的客户端,需要向ServiceManger注册服务
//调用defaultServiceManager,得到一个IServiceManager。
sp<IServiceManager>sm = defaultServiceManager();
//初始化音频系统的AudioFlinger服务
AudioFlinger::instantiate();
//③多媒体系统的MediaPlayer服务,我们将以它作为主切入点
MediaPlayerService::instantiate();
//CameraService服务
CameraService::instantiate();
//音频系统的AudioPolicy服务
AudioPolicyService::instantiate();
//④根据名称来推断,难道是要创建一个线程池吗?
ProcessState::self()->startThreadPool();
//⑤下面的操作是要将自己加入到刚才的线程池中吗?
IPCThreadState::self()->joinThreadPool();
}

主要分为5个步骤。

ProcessState::self()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ProcessState::ProcessState()
// Android的中有很多代码都是这么写的,稍不留神就容易忽略这里调用了一个很重要的函数
:mDriverFD(open_driver())
,mVMStart(MAP_FAILED)//映射内存的起始地址
,mManagesContexts(false)
,mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
,mThreadPoolStarted(false)
,mThreadPoolSeq(1)
{
if(mDriverFD >= 0) {
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,MAP_PRIVATE | MAP_NORESERVE,
mDriverFD, 0);
}
}
1
2
3
4
5
6
7
8
9
10
static int open_driver()
{
int fd =open("/dev/binder", O_RDWR);//打开/dev/binder设备
if (fd>= 0) {
size_t maxThreads = 15;
//通过ioctl方式告诉binder驱动,这个fd支持的最大线程数是15个
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
}
return fd;
}

ProcessState::self()主要做了三件事情

  1. 打开/dev/binder设备,同内核进行Binder通讯
  2. 返回fd使用mmap,分配内存接收数据
  3. PressessState是单例模式
defaultServiceManager
1
2
3
4
5
6
7
8
9
10
11
sp<IServiceManager> defaultServiceManager()
{
f(gDefaultServiceManager != NULL) return gDefaultServiceManager;
......
if(gDefaultServiceManager == NULL) {
//真正的gDefaultServiceManager是在这里创建的。
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;

单例模式,创建getContextObject(NULL)

1
2
3
4
5
6
sp<IBinder>ProcessState::getContextObject(const sp<IBinder>& caller)
{
......
return getStrongProxyForHandle(0);
......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
sp<IBinder>ProcessState::getStrongProxyForHandle(int32_t handle)
{
if (b== NULL || !e->refs->attemptIncWeak(this)) {
//对于新创建的资源项,它的binder为空,所以走这个分支。注意,handle的值为0
b= new BpBinder(handle); //创建一个BpBinder
e->binder = b; //填充entry的内容
if (b) e->refs = b->getWeakRefs();
result = b;
}else {
result.force_set(b);
e->refs->decWeak(this);
}
}

创建BpBinder如果handle == 0

BpBinder分析

BpBinder和BBinder都是继承到IBinder。

  • BpBinder是客户端Server的代理类
  • BBinder是proxy的相对的一端,相对于BpBinder来说,BBinder就是服务端