Android7.0 Binder通信(1) ServiceManger

这篇博客详细介绍了Android 7.0中的Binder通信,特别是ServiceManager如何作为系统服务的管理者,负责服务的注册、查询和状态监控。文章通过分析源码揭示了ServiceManager的启动过程和服务管理功能。
摘要由CSDN通过智能技术生成

背景
Android是基于Linux的操作系统,在其中运行的应用或者系统服务,实际上就是一个个Linux进程。这意味着它们彼此之间是隔离的,必须通过进程间通信(IPC)来相互传输数据。Binder就是Android实现的一种IPC通信方式。

然而我们知道,Linux已经提供了一些进程间通信的机制,例如socket和pipes等,为什么Android还要重新“造轮子”,创造一种新的IPC机制呢?
为了弄明白这个问题,自己参考了一些外文资料,其中比较让人信服的答案是:为了更好的性能。

我们知道Android中所有的系统功能都是由不同的服务进程提供的。
客户进程如果想使用某个功能,必须发送请求给对应的服务进程,然后等待结果。
由于Android有大量的这种通信需求,因此整个系统内部可能会频繁地发生进程间通信。也就是说,Android对进程间通信有高度的依赖性。
Android为了提高系统整体的传输效率,需要一种优化过的进程间通信方式。于是,Binder机制应运而生。

Binder机制起源于一个简单的想法:将申请服务的请求和对应的响应信息,写入一个所有进程均能够访问的地址空间中。
当进程需要使用这些数据时,只需要访问对应的内存地址,以减小内容复制引入的开销。
为此,Binder机制利用kernel空间作为共享区域,并由Binder driver来建立起每个进程的内存地址与kernel空间中存储地址的映射。


版本
android 7.0

Binder通信的整体架构
引入了Binder机制后,Android中基于Binder的进程间通信,整体上仍是一种C/S结构。


1.如上图所示,ServiceManger负责管理系统中的各种服务。Server进程首先要注册一些服务一些服务到ServiceManager中,所以在这个过程中,Server进程是ServiceManager的客户端。
2.如果某个Client进程要使用某个Service,必须先到ServiceManager中获取该Service相关的信息,所以在此过程中,Client进程是ServiceManager的客户端。
3.Client进程获取到Service信息,与Server进程建立通信后,就可以直接与Server进程通信了,在此过程中Client进程是Server进程的客户端。

以上3种通信方式,均是基于Binder通信的,我们将按照先后顺序依次分析:ServiceManager,Server进程的注册,Client进程的查询及使用。
在这篇博客中,我们先一起看一下ServiceManager中主要的流程。

ServiceManager

1 服务启动

service servicemanager /system/bin/servicemanager
    class core
    user system
    group system readproc
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart audioserver
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart inputflinger
    onrestart restart drm
    onrestart restart cameraserver
    writepid /dev/cpuset/system-background/tasks

如上所示,在android7.0中,文件frameworks/native/cmds/servicemanager/servicemanager.rc文件中定义了servicemanager,可以看到servicemanager对应的keyword是service。在分析init进程时,我们知道init进程解析rc文件时,遇到service关键字后,仅利用其后的信息构造出service对象,并不会立即启动service。
那么servicemanager是如何被加载的呢?

在init.rc中,定义了early-init, init, late-init, early-boot, boot这样的字段,以定义命令的先后执行顺序,在init.cpp的main函数中有:

.............
ActionManager& am = ActionManager::GetInstance();
am.QueueEventTrigger("early-init");
.............
am.QueueEventTrigger("init");
.............
am.QueueEventTrigger("late-init");

可以明显的看到,这些字段对应的触发事件被先后加入到执行队列中。在init.rc中:

on late-init
    ......
    trigger early-boot
    trigger boot

可以看到在late-init对应的一系列执行命令的最后,将触发操作early-boot和boot阶段。

在boot阶段的最后:

on boot
    .......
    class_start core

看到没?在boot阶段的最后,将要进行class_start core的操作。在system/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值