Android-IPC系列(二)

前言

写完IPC的第一篇我就有点后悔了。。因为binder的水太深了,老罗写binder写了十几万字。如果深入学习会大量涉及到系统层的知识,甚至SM,Binder驱动都是用c语言写的。。最近也是看了很多大牛关于binder的文章,可以说对binder的认识又提升了一步。虽然我学的很浅,但是我尽量保证自己写的都是对的! 来一波binder的最新认识总结吧!~

Android_IPC系列(一)

上一篇文章主要是介绍一些简单的linux知识,通过AIDL中的生成代码来理解binder实现跨进程的原理。

任务:

  1. 补充一些Linux知识。
  2. binder实现跨进程通信的实现流程是怎样的
  3. 简单介绍binder机制

一些补充知识

1.UserSpace, KernelSpace ,用户态,内核态

用户空间和内核空间。内核空间是linux系统的核心,可以访问受保护资源和所有的硬件设备的权限。内核独立于应用程序,看起来是系统内部的一个应用。kernel有自己的保护措施,告知其他应用程序他拥有什么权限。所以在逻辑上,将kernal和应用程序抽离成两块空间。

当某个应用程序需要访问内核资源的时候,可以通过系统调用来接入内核。然后内核会来控制这个应用程序对资源的访问,防止这个程序破坏系统资源,保证安全。这时候就会称这个进程处于内核态 。当应用程序在跑自己的代码的时候,就称为用户态

2.Binder驱动

Linux系统内部是支持socket,信号量等进程通信的,但是安卓系统在性能和安全两个方面设计了自己的进程通信方式:Binder。两个用户空间想要通信,必须通过内核空间来支持。所以安卓就是将binder驱动作为内核模块添加到Linux Kernel。Binder驱动运行在kernel空间,支持用户空间的通信,可以堪称一个桥梁,所有包含binder的数据包传输都会通过binder驱动来完成,无一例外!在binder驱动里面,binder的实体和引用是以节点(struct)的形式存在的,包括server的binder实体,clinet里面拥有的binder引用,内核的0号应用以及SM的binder实体(后两者后面会提到)。

驱动是Binder通信的核心,系统中所有的Binder实体以及每个实体在各个进程中的引用都登记在驱动中;驱动需要记录Binder引用->实体之间多对一的关系;为引用找到对应的实体;在某个进程中为实体创建或查找到对应的引用;记录Binder的归属地(位于哪个进程中);通过管理Binder的强/弱引用创建/销毁Binder实体等等。

3.ServiceManager, Binder,Clinet, Server

在Binder的机制中,SM, Clinet, Server以及上面提到的Binder驱动是很重要的四个部分,而binder就可以看成是这四个部件之间沟通的管道。但是binder在每个部件里面的形态,功能是完全不同的。宏观来看,binder可以看成是安卓跨进程通信的方式,工具,协议。微观的来看,binder可以看成各个部件里面重要的结构,类,binder可以看成binder驱动里面的红黑树数据结构,binder可以看成进程之间传输的数据包。binder作为胶水,将不同的进程粘合在一起,模糊了进程隔离。

ServiceManager是独立于client, server的系统进程。是由zygote进程fork出来的。它在IPC通信中的作用是作为"通讯录"。所有的server里面的binder实体会先在SM里面注册自己的信息,key是binder的名字(独一无二),在AIDL的生成代码里面你会看到这个玩意:

private static final java.lang.String DESCRIPTOR ="com.example.zane.ipc_test.IBookManager";

value就是这个binder的引用,这样就把这个binder的信息保存下来了。也就是说client需要通过SM,以名字来去得到server的binder引用。然后通过这个引用去操作server端的binder。这里也体现了binder中面向对象的设计理念。clinet自己并不知道自己获得的这个binder引用是真的实体还是什么假的实体,它只会去拿着自己获得的引用去操作。并且server中binder实体的引用会在SM,和所有需要跟自己通信的clinet里面存在。在这里,你可以把引用看成指针,或者代理对象。

client和server就是客户端和服务端。

在服务端:如果你熟悉AIDL进行进程间通信的流程或者看过我上篇博客,你应该对binder的存在形式有所体会。首先是一个aidl类型的接口,定义了binder的所有功能函数。并且这些功能函数需要被编号,因为服务端是通过解析客户端传递过来的数据包中的函数编号来知道自己应该去调用什么函数。在Stub类中有这么几行代码(函数编号):

static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);

我们知道Stub就是Binder在Server的实体,里面实现了很多函数,onTransact()就是来分析客户端的请求类型的函数,然后调用相应的函数,并且将返回结果放在数据包中返回给客户端。

在客户端:同样的,我们在客户端也需要去实现Binder,只不过这个binder是SM转发给我们的,如果客户端和服务端在同一个进程,那么就会返回binder实体,如果不在同一个进程就会返回binder的代理。由于binder代理和binder实体都是实现了AIDL接口的类。所以客户端看不出来这个binder是实体或是引用。如果你做过IPC通信,你会知道以上的过程是通过asInterface(IBiner binder)这个方法实现的。


实现流程

直接上一张我自己画的简介图!

简介图
简介图

可以很清楚的看出,binder驱动是整个流程的核心!

1.Server将自己的binder通过binder驱动在SM中进行注册。

2.binder驱动会建立一个binder实体的数据节点和实体的引用。

3.Binder驱动再把名字和引用打包发给SM。

4.Client通过binder驱动拿着他所需要的binder名字向SM请求binder。

5.SM在自己的查找表里面找到对应的引用之后再通过binder驱动返回给client。

所有的系统服务在SystemServer进程深沉之后就会被建立并且注册在ServiceManager里面,开发者也可以开发自定义的服务并且注册在ServiceManager里面成为系统级别的服务,前提是这个包含服务的应用必须是system用户并且带了system签名(系统安全),否则是不能随意注册的!

好了,再来一张我在一位大牛博客里面截下来的图片,这个流程描述就更具体了:

ipc2-2.png

其实就是多了binder驱动里面的一些数据结构节点和一个叫0号引用的东西。那么这个0号引用是什么呢?我们知道SM, Client, Server都是运行在三个不同的进程的。那么第一步Server要向SM注册自己binder的信息,那么这里已经涉及到了跨进程通信了。那么这个进程通信是怎么实现的呢?通过上图可以看到,所有的Client里面的0号引用都指向了SM里面的binder。也就是说SM和其他所有Server通信的过程都是SM先通过特殊的命令在biner驱动中建立了自己binder的实体节点,并且其他所有地方的0号引用都默认留给SM的binder实体引用。


结束语

上一篇文章讲的AIDL生成代码的分析,本来准备第二篇总结一下AIDL的使用。后来通过不断的学习觉得这篇文章讲的东西更值得总结!

总之,binder要学习的东西还是很多。比如binder协议,binder传输数据包类型,binder在驱动里面的数据结构,缓存和线程池管理等等…Binder在安全性,效率性都优于Linux系统默认支持的IPC通信方式,拥有面向对象的设计原理。

未经博主同意,不得转载该篇文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容