您现在的位置是: 首页 > 策略塔防 策略塔防

binder_binder恒温恒湿箱

zmhk 2024-05-31 人已围观

简介binder_binder恒温恒湿箱       接下来,我将会为大家提供一些有关binder的知识和见解,希望我的回答能够让大家对此有更深入的了解。下面,我们开始探讨一下binder的话题。1.如

binder_binder恒温恒湿箱

       接下来,我将会为大家提供一些有关binder的知识和见解,希望我的回答能够让大家对此有更深入的了解。下面,我们开始探讨一下binder的话题。

1.如何在android面试中说清楚android中binder机制的实现过程

2.binder综合症国内比例

3.binder一次传递的数据最大是多少

4.Android为什么选择binder

5.Linux的IPC机制(三):Binder

binder_binder恒温恒湿箱

如何在android面试中说清楚android中binder机制的实现过程

        Binder是Android系统中的一种IPC进程间通信结构。

       Binder的整个设计是C/S结构,客户端进程通过获取服务端进程的代理,并通过向这个代理接口方法中读写数据来完成进程间的数据通信。

       Android之所以选择Binder,我觉得有2个方面的原因。

       1是安全,每个进程都会被Android系统分配UID和PID,不像传统的在数据里加入UID,这就让那些恶意进程无法直接和其他进程通信,进程间通信的安全性得到提升。

       2是高效,像Socket之类的IPC每次数据拷贝都需要2次,而Binder只要1次,在手机这种资源紧张的情况下很重要。

binder综合症国内比例

       Android系统底层协议解析

       作为目前全球最为广泛使用的移动操作系统之一,Android系统的位置不言自明。无论是在日常生活中,还是在商业领域中,都可以感受到Android系统带来的便利和创造力。而其中非常重要的一环便是Android系统的底层协议。

       Android系统的底层协议指的是一套能够实现系统内部数据传输和协调的规则和标准。它是由Android系统架构的各组件和级别之间形成的通信桥梁,能够促进系统之间的信息互换和共享。其中,Android系统最为重要的两个协议是:Binder和Socket。

       Binder协议是一种混合式IPC协议,它是Android系统中间件中最为重要的通信机制。在Binder机制的实现中,服务端通过LocalBinder和客户端通过Stub与代理Binder通信,最终可以在各个进程之间强制调用服务。Binder机制的运作原理主要是通过一个Binder对象,完成了在客户端和服务端之间的数据交换,无需开发人员自己实现IPC功能。它可以通过进程间通信(IPC)将进程之间的内存空间进行共享,使进程可以直接共享内存数据,而无需通过缓存提供一组抽象的接口。

       Socket协议则是介于应用层和传输层的传输层协议,它是一种电子管通信的方式,是安卓系统网络通讯的一种方式。Socket协议支持TCP/IP和UDP/IP等主流通信协议,具有稳定,可靠,通用性强等优点,也因此成为了Android系统中最为重要的一种通信机制。

       总的来说,Android系统的底层协议对于整个系统运行和通信起到了非常重要的作用。它们可以促进各组件之间的互动,使得系统的运作可以更加稳定快捷。因此,在设计移动应用程序的过程中,必须考虑到Android系统的底层协议,从而使程序在运行中更多情况下能够顺利完成各个层次的数据处理和传输。最终达到用户所期望的可靠性和效率。

binder一次传递的数据最大是多少

       8:2。Binder综合症”又称先天性中面部凹陷,通俗点说就是中面部及鼻部在不同程度上发育不良,且这类病症在东方人中的发病率不算低,有研究人员称在我国发病比例在8:2;且这种病是遗传的,97例binder综合征的患儿进行研究,发现存在确切家族史的患者比率高达36%。

Android为什么选择binder

       Binder主要能提供以下一些功能:

       用驱动程序来推进进程间的通信。

       通过共享内存来提高性能。

       为进程请求分配每个进程的线程池。

       针对系统中的对象引入了引用计数和跨进程的对象引用映射。

       进程间同步调用。

Linux的IPC机制(三):Binder

       Binder主要能提供以下一些功能:

       用驱动程序来推进进程间的通信。

       通过共享内存来提高性能。

       为进程请求分配每个进程的线程池。

       针对系统中的对象引入了引用计数和跨进程的对象引用映射。

       进程间同步调用。

       Android Binder设计与实现 – 设计篇:

       目前linux支持的IPC包括传统的管道、System V IPC、即消息队列/共享内存/信号量,以及socket中只有socket支持Client-Server的通信方式。

       当然也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。

       另一方面是传输性能:

       socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。

       消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,

       至少有两次拷贝过程。共享内存虽然无需拷贝,但控制复杂,难以使用。

       还有一点是出于安全性考虑:

       Android作为一个开放式,拥有众多开发者的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。

       终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。传统IPC没有任何

       安全措施,完全依赖上层协议来确保。首先传统IPC的接收方无法获得对方进程可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份。

       Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID/PID,

       但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。

       比如命名管道的名称、system V的键值、socket的ip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法

       阻止恶意程序通过猜测接收方地址获得连接。

       基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。

       Binder基于 Client-Server通信模式,传输过程只需一次拷贝,为发送发添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。

       面向对象的 Binder IPC:

        面向对象思想的引入将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个

       可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。最诱人的是,这个引用和java里引用

       一样既可以是强类型,也可以是弱类型,而且可以从一个进程传给其它进程,让大家都能访问同一Server,就像将一个对象或引用赋

       值给另一个引用一样。Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。

       面向对象只是针对应用程序而言,对于Binder驱动和内核其它模块一样使用C语言实现,没有类和对象的概念。

       Binder驱动为面向对象的进程间通信提供底层支持。

        正如上一章所说, 跨进程通信是需要内核空间做支持的. 传统的 IPC 机制如 管道, Socket, 都是内核的一部分, 因此通过内核支持来实现进程间通信自然是没问题的.

        但是 Binder 并不是 Linux 系统内核的一部分, 那怎么办呢, 这得益于 Linux 的动态内核可加载模块 (Loadable Kernel Module, LKM)的机制

        这样 Android 系统就可以通过动态添加一个内核模块运行在内核空间, 用户进程进程之间通过这个内核模块作为桥梁来实现通信.

        那么在 Android 系统中用户进程之间是如何通过这个内核模块 (Binder Driver)来实现通信的呢? 显然不是和上一章的传统 IPC 通信一样,进行两次 copy 了, 不然Binder 也不有在性能方面的优势了.

        Binder IPC 机制中设计到的内存映射通过 mmap() 来实现, mmap() 是操作系统中一种内存映射的方法.

        内存映射能减少数据 copy 的次数, 实现用户空间和内核空间的高效互动. 两个空间各自的修改也能直接反应在映射的内存区域, 从而被对方空间及时感知. 也正因为如此, 内存映射能够提供对进程间通信的支持.

        Binder IPC 正是基于内存映射( mmap() ) 来实现的, 但是 mmap() 通常是用在有物理介质的文件系统上的.

        比如进程中的用户区域是不能直接和物理设备打交道的, 如果想要把磁盘上的数据读取到进程的用户区域, 需要两次 copy (磁盘 -> 内核空间 -> 用户空间). 通常在这种场景下 mmap() 就能发挥作用, 通过在物理介质和用户空间之间建立映射, 减少数据的 copy 次数, 用内存读写代替 I/O 读写, 提高文件读取效率.

        而 Binder 并不存在物理介质, 因此 Binder 驱动使用 mmap() 并不是为了在物理介质和用户空间之间映射, 而是用来在内核空间创建数据接收的缓存空间.

        一次完整的 Binder IPC 通信过程通常是这样:

        这样就完成了一次进程间通信

        如下图:

        介绍完 Binder IPC 的底层通信原理, 接下来我们看看实现层面是如何设计的

        一次完成的进程间通信必然至少包含两个进程, 通常我们称通信的双方分别为客户端进程(Client) 和服务端进程(Server), 由于进程隔离机制的存在, 通信双方必然需要借助 Binder 来实现.

        BInder 是基于 C/S 架构. 是由一些列组件组成. 包括 Client, Server, ServiceManager, Binder 驱动.

        Binder 驱动就如如同路由器一样, 是整个通信的核心. 驱动负责进程之间 Binder 通信的建立 / 传递, Binder 引用计数管理, 数据包在进程之间的传递和交互等一系列底层支持.

        ServiceManager 作用是将字符形式的 Binder 名字转化成 Client 中对该 Binder 的引用, 使得 Client 能够通过 Binder 的名字获得对 Binder 实体的引用.

        注册了名字的 Binder 叫实名 Binder, 就像网站一样除了 IP 地址以外还有自己的网址.

        Server 创建了 Binder, 并为它起一个字符形式, 可读易记的名字, 将这个 BInder 实体连同名字一起以数据包的形式通过 Binder 驱动 发送给 ServiceManager, 通知 ServiceManager 注册一个名字为 "张三"的 Binder, 它位于某个 Server 中, 驱动为这个穿越进程边界的 BInder 创建位于内核中的实体节点以及 ServiceManager 对实体的引用, 将名字以及新建的引用打包传给 ServiceManager, ServiceManager 收到数据后从中取出名字和引用填入查找表.

        ServiceManager 是一个进程, Server 又是一个另外的进程, Server 向 ServiceManager 中注册 BInder 必然涉及到进程间通信. 当实现进程间通信又要用到进程间通信, 这就好像蛋可以孵出鸡的前提确实要先找只鸡下蛋! Binder 的实现比较巧妙, 就是预先创造一只鸡来下蛋. ServiceManager 和其他进程同样采用 Binder 通信, ServiceManager 是 Server 端, 有自己的 Binder 实体, 其他进程都是 Client, 需要通过这个 Binder 的引用来实现 Binder 的注册, 查询和获取. ServiceManager 提供的 Binder 比较特殊, 它没有名字也不需要注册. 当一个进程使用 BINDERSETCONTEXT_MGR 命令将自己注册成 ServiceManager 时 Binder 驱动会自动为它创建 Binder 实体(这就是那只预先造好的那只鸡). 其实这个 Binder 实体的引用在所有 Client 中都固定为 0 , 而无需通过其他手段获得. 也就是说, 一个 Server 想要向 ServiceManager 注册自己的 Binder 就必须通过这个 0 号引用和 ServiceManager 的 Binder 通信. 这里说的 Client 是相对于 ServiceManager 而言的, 一个进程或者应用程序可能是提供服务的 Server, 但是对于 ServiceManager 来说它仍然是个 Client.

        Server 向 ServiceManager 中注册了 Binder 以后, Client 就能通过名字获得 Binder 的引用. Client 也利用保留的 0 号引用向 ServiceManager 请求访问某个 Binder. 比如,Client 申请访问名字叫"张三"的 Binder 引用. ServiceManager 收到这个请求后从请求数据包中取出 Binder 名称, 在查找表里找到对应的条目, 取出对应的 Binder 引用, 作为回复发送给发起请求的 Client. 从面相对象的角度看, Server 中的 Binder 实体现在有两个引用: 一个位于 ServiceManager 中, 一个位于发起请求的 Client 中. 如果后面会有更多的 Client 请求该 Binder, 系统中就会有更多的引用指向这个 Binder, 就像 Java 中一个对象有多个引用一样.

        我们已经解释清楚 Client, Server 借助 Binder 驱动完成跨进程通信的实现机制了, 但是还有个问题需要弄清楚, 比如 A 进程想要 B 进程中的某个对象(object) 是如何实现的呢, 毕竟它们属于不同的进程, A 进程没办法直接使用 B 进程中的 object.

        前面我们说过跨进程通信的过程都有 Binder 驱动的参与, 因此在数据流经 Binder 驱动的时候 Binder 驱动会对数据做一层转换.

        我们在 Client端,向 ServiceManager 获取具体的 Server 端的 Binder 引用的时候,会首先进过 Binder 驱动,Binder 驱动它并不会把真正的 Server 的 Binder 引用返回给 Client 端,而是返回一个代理的 java 对象,该对象具有跟 Server 端的 Binder 引用相同的方法签名,这个对象为 ProxyObject,他具有跟 Server 的 Binder 实例一样的方法,只是这些方法并没有 Server 端的能力,这些方法只需要把请求参数交给 Binder 驱动即可. 对于 Client 端来说和直接调用 Server 中的方法是一样的.

        了解了上面之后, 我们大致可以推算出 Binder 的通信过程

        1. 注册 ServiceManager

        2. 注册 Server

        3. Client 获取 Server 的 Binder 引用

        4. Client 与 Server 通信

       好了,今天关于“binder”的话题就讲到这里了。希望大家能够通过我的介绍对“binder”有更全面、深入的认识,并且能够在今后的实践中更好地运用所学知识。