Binder这么弱还跑来面试腾讯?ServiceManager中的Binder机制

本文深入探讨了Android Binder通信的C/S架构,以MediaServer为例,详细解析了ServiceManager如何管理服务,包括Server进程注册Service、Client通过ServiceManager查找和通信的过程。同时,分析了ProcessState在Binder通信中的角色,阐述了BpBinder、BBinder以及IServiceManager家族的工作原理。
摘要由CSDN通过智能技术生成

 

前言

Binder机制的三个部分:Java Binder、Native Binder、Kernel Binder,其中Java Binder和Native Binder都是应用开发需要掌握的。Java Binder是需要借助Native Binder来工作的,因此需要先了解Native Binder,Native Binder架构的原型就是基于Binder通信的C/S架构,因此我们先从它开始入手。源码是基于Android 9.0。

1.基于Binder通信的C/S架构

在Android系统中,Binder进程间的通信的使用是很普遍的,在Android进阶三部曲第一部的最后一章,我讲解了MediaPlayer框架,这个框架基于C/S架构,并采用Binder来进行进程间通信,如下图所示。

 

从图中可以看出,除了常规C/S架构的Client端和Server端,还包括了ServiceManager,它用于管理系统中的服务。
首先Server进程会注册一些Service到ServiceManager中,Client要使用某个Service,则需要先到ServiceManager查询Service的相关信息,然后根据Service的相关信息与Service所在的Server进程建立通信通路,这样Client就可以使用Service了。

2.MediaServer的main函数

Client、Server、ServiceManager三者的交互都是基于Binder通信的,那么任意两者的交互都可以说明Binder的通信的原理,可以说Native Binder的原理的核心就是ServiceManager的原理,为了更好的了解ServiceManager,这里拿MediaPlayer框架来举例,它也是学习多媒体时必须要掌握的知识点。

MediaPlayer框架的简单框架图如下所示:

 

可以看到,MediaPlayer和MediaPlayerService是通过Binder来进行通信的,MediaPlayer是Client端,MediaPlayerService是Server端,MediaPlayerService是系统多媒体服务的一种,系统多媒体服务是由一个叫做MediaServer的服务进程提供的,它是一个可执行程序,在Android系统启动时,MediaServer也被启动,它的入口函数如下所示。

frameworks/av/media/mediaserver/main_mediaserver.cpp

int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);
    //获取ProcessState实例
    sp<ProcessState> proc(ProcessState::self());//1
    sp<IServiceManager> sm(defaultServiceManager());//2
    ALOGI("ServiceManager: %p", sm.get());
    InitializeIcuOrDie();
    //注册MediaPlayerService
    MediaPlayerService::instantiate();//3
    ResourceManagerService::instantiate();
    registerExtensions();
    //启动Binder线程池
    ProcessState::self()->startThreadPool();
    //当前线程加入到线程池
    IPCThreadState::self()->joinThreadPool();
}

注释1处用于获取ProcessState实例,在这一过程中会打开/dev/binder设备,并使用mmap为Binder驱动分配一个虚拟地址空间用来接收数据。
注释2处用来得到一个IServiceManager,通过这个IServiceManager,其他进程就可以和当前的ServiceManager进行交互,这里就用到了Binder通信。
注释3处用来注册MediaPlayerService。
除了注释3处的知识点在下一篇文章进行介绍,注释1和注释2处的内容,本篇文章会分别来进行介绍,先看ProcessState实例。

3.每个进程唯一的ProcessState

ProcessState从名称就可以看出来,用于代表进程的状态,先来查看上一小节的ProcessState的self函数。

frameworks/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");//1
    return gProcess;
}

这里采用了单例模式,确保每个进程只有一个ProcessState实例。注释1处用于创建一个ProcessState实例,参数为/dev/binder。接着来查看ProcessState的构造函数,代码如下所示。

frameworks/native/libs/binder/ProcessState.cpp

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))//1
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALI
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值