您当前的位置:首页 > 生活 > 内容

binder机制(android进程间的通信有aidl和binder机制,请问两者的原理是什么,以及两者的区别是什么)

本文目录

  • android进程间的通信有aidl和binder机制,请问两者的原理是什么,以及两者的区别是什么
  • android binder 机制原理,能具体讲讲吗不要粘贴,要自己的理解o
  • 如何在android面试中说清楚android中binder机制的实现过程
  • Linux的IPC机制(三):Binder
  • android开发学懂binder机制有什么好处
  • 为什么Android要采用Binder作为IPC机制
  • 安卓系统的binder通信机制和intent通信机制的不同之处
  • 为什么 Android 要采用 Binder 作为 IPC 机制
  • 如何在Android下使用Binder

android进程间的通信有aidl和binder机制,请问两者的原理是什么,以及两者的区别是什么

binder是内核层的驱动程序,相当于协议之类的东西,aidl其实是rpc,也是进程间的通信,底层也是基于binder机制的

android binder 机制原理,能具体讲讲吗不要粘贴,要自己的理解o

binder在安卓中有个中间代理人的身份,就像是街头贴小广告的,他能提供一些特殊服务...,安卓开发中开启服务的方式有两种,一种是onStartCommand直接开启服务,这种服务开启之后如果不stopservice关闭服务的话,它会在后台一直运行,还有一种就是通过bindservice的方法开启服务,这种方法就是绑定服务,绑定之后会随着activity的关闭而销毁..在绑定服务的时候可以写一个内部类继承binder,然后再调用的时候可以写一个内部类实现serviceconnection接口,,在onServiceConnected的方法中会返回一个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次,在手机这种资源紧张的情况下很重要。

Linux的IPC机制(三):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 通信

android开发学懂binder机制有什么好处

本身binder通信就是一些比较底层的东西,App开发中并不需要对binder的机制有太深入的了解,如果是ROM开发的话,那就需要懂的比较多了

为什么Android要采用Binder作为IPC机制

1)从性能的角度数据拷贝次数:Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。(2)从稳定性的角度Binder是基于C/S架构的,简单解释下C/S架构,是指客户端(Client)和服务端(Server)组成的架构,Client端有什么需求,直接发送给Server端去完成,架构清晰明朗,Server端与Client端相对独立,稳定性较好;而共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题;从这稳定性角度看,Binder架构优越于共享内存。仅仅从以上两点,各有优劣,还不足以支撑google去采用binder的IPC机制,那么更重要的原因是:(3)从安全的角度传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Android作为一个开放的开源体系,拥有非常多的开发平台,App来源甚广,因此手机的安全显得额外重要;对于普通用户,绝不希望从App商店下载偷窥隐射数据、后台造成手机耗电等等问题,传统Linux IPC无任何保护措施,完全由上层协议来确保。 Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志,前面提到C/S架构,Android系统中对外只暴露Client端,Client端将任务发送给Server端,Server端会根据权限控制策略,判断UID/PID是否满足访问权限,目前权限控制很多时候是通过弹出权限询问对话框,让用户选择是否运行。Android 6.0,也称为Android M,在6.0之前的系统是在App第一次安装时,会将整个App所涉及的所有权限一次询问,只要留意看会发现很多App根本用不上通信录和短信,但在这一次性权限权限时会包含进去,让用户拒绝不得,因为拒绝后App无法正常使用,而一旦授权后,应用便可以胡作非为。针对这个问题,google在Android M做了调整,不再是安装时一并询问所有权限,而是在App运行过程中,需要哪个权限再弹框询问用户是否给相应的权限,对权限做了更细地控制,让用户有了更多的可控性,但同时也带来了另一个用户诟病的地方,那也就是权限询问的弹框的次数大幅度增多。对于Android M平台上,有些App开发者可能会写出让手机异常频繁弹框的App,企图直到用户授权为止,这对用户来说是不能忍的,用户最后吐槽的可不光是App,还有Android系统以及手机厂商,有些用户可能就跳果粉了,这还需要广大Android开发者以及手机厂商共同努力,共同打造安全与体验俱佳的Android手机。

安卓系统的binder通信机制和intent通信机制的不同之处

它们都是串行通讯是没错的,区别I2C同步传送,也没是说每传一位都要一个同步时钟脉冲(脉冲是SCL发出),接收和发送数据都是用SDA,UART则不需要同步时钟脉冲,UART则是通过TXD发,RXD收,它是通过设置好一个固定通讯速率传送数据的,这个速率就是我们所说的波特率了。我相信楼主现在应该明白了哦!

为什么 Android 要采用 Binder 作为 IPC 机制

1)从性能的角度数据拷贝次数:Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。(2)从稳定性的角度Binder是基于C/S架构的,简单解释下C/S架构,是指客户端(Client)和服务端(Server)组成的架构,Client端有什么需求,直接发送给Server端去完成,架构清晰明朗,Server端与Client端相对独立,稳定性较好;而共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题;从这稳定性角度看,Binder架构优越于共享内存。仅仅从以上两点,各有优劣,还不足以支撑google去采用binder的IPC机制,那么更重要的原因是:(3)从安全的角度传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Android作为一个开放的开源体系,拥有非常多的开发平台,App来源甚广,因此手机的安全显得额外重要;对于普通用户,绝不希望从App商店下载偷窥隐射数据、后台造成手机耗电等等问题,传统Linux IPC无任何保护措施,完全由上层协议来确保。 Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志,前面提到C/S架构,Android系统中对外只暴露Client端,Client端将任务发送给Server端,Server端会根据权限控制策略,判断UID/PID是否满足访问权限,目前权限控制很多时候是通过弹出权限询问对话框,让用户选择是否运行。Android 6.0,也称为Android M,在6.0之前的系统是在App第一次安装时,会将整个App所涉及的所有权限一次询问,只要留意看会发现很多App根本用不上通信录和短信,但在这一次性权限权限时会包含进去,让用户拒绝不得,因为拒绝后App无法正常使用,而一旦授权后,应用便可以胡作非为。针对这个问题,google在Android M做了调整,不再是安装时一并询问所有权限,而是在App运行过程中,需要哪个权限再弹框询问用户是否给相应的权限,对权限做了更细地控制,让用户有了更多的可控性,但同时也带来了另一个用户诟病的地方,那也就是权限询问的弹框的次数大幅度增多。对于Android M平台上,有些App开发者可能会写出让手机异常频繁弹框的App,企图直到用户授权为止,这对用户来说是不能忍的,用户最后吐槽的可不光是App,还有Android系统以及手机厂商,有些用户可能就跳果粉了,这还需要广大Android开发者以及手机厂商共同努力,共同打造安全与体验俱佳的Android手机。Android中权限控制策略有SELinux等多方面手段,下面列举从Binder的一个角度的权限控制:Android源码的Binder权限是如何控制? -Gityuan的回答传统IPC只能由用户在数据包里填入UID/PID;另外,可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。从安全角度,Binder的安全性更高。说到这,可能有人要反驳,Android就算用了Binder架构,而现如今Android手机的各种流氓软件,不就是干着这种偷窥隐射,后台偷偷跑流量的事吗?没错,确实存在,但这不能说Binder的安全性不好,因为Android系统仍然是掌握主控权,可以控制这类App的流氓行为,只是对于该采用何种策略来控制,在这方面android的确存在很多有待进步的空间,这也是google以及各大手机厂商一直努力改善的地方之一。在Android 6.0,google对于app的权限问题作为较多的努力,大大收紧的应用权限;另外,在Google举办的Android Bootcamp 2016大会中,google也表示在Android 7.0 (也叫Android N)的权限隐私方面会进一步加强加固,比如SELinux,Memory safe language(还在research中)等等,在今年的5月18日至5月20日,google将推出Android N。 (4)从语言层面的角度大家多知道Linux是基于C语言(面向过程的语言),而Android是基于Java语言(面向对象的语句),而对于Binder恰恰也符合面向对象的思想,将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。可以从一个进程传给其它进程,让大家都能访问同一Server,就像将一个对象或引用赋值给另一个引用一样。Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。从语言层面,Binder更适合基于面向对象语言的Android系统,对于Linux系统可能会有点“水土不服”。另外,Binder是为Android这类系统而生,而并非Linux社区没有想到Binder IPC机制的存在,对于Linux社区的广大开发人员,我还是表示深深佩服,让世界有了如此精湛而美妙的开源系统。也并非Linux现有的IPC机制不够好,相反地,经过这么多优秀工程师的不断打磨,依然非常优秀,每种Linux的IPC机制都有存在的价值,同时在Android系统中也依然采用了大量Linux现有的IPC机制,根据每类IPC的原理特性,因时制宜,不同场景特性往往会采用其下最适宜的。比如在Android OS中的Zygote进程的IPC采用的是Socket(套接字)机制,Android中的Kill Process采用的signal(信号)机制等等。而Binder更多则用在system_server进程与上层App层的IPC交互。(5) 从公司战略的角度总所周知,Linux内核是开源的系统,所开放源代码许可协议GPL保护,该协议具有“病毒式感染”的能力,怎么理解这句话呢?受GPL保护的Linux Kernel是运行在内核空间,对于上层的任何类库、服务、应用等运行在用户空间,一旦进行SysCall(系统调用),调用到底层Kernel,那么也必须遵循GPL协议。 而Android 之父 Andy Rubin对于GPL显然是不能接受的,为此,Google巧妙地将GPL协议控制在内核空间,将用户空间的协议采用Apache-2.0协议(允许基于Android的开发商不向社区反馈源码),同时在GPL协议与Apache-2.0之间的Lib库中采用BSD证授权方法,有效隔断了GPL的传染性,仍有较大争议,但至少目前缓解Android,让GPL止步于内核空间,这是Google在GPL Linux下 开源与商业化共存的一个成功典范。

如何在Android下使用Binder

 实现一个binder通信实例,需要经过以下步骤:  (1)获得ServiceManager的对象引用  (2)向ServiceManager注册新的Service  (3)在Client中通过ServiceManager获得Service对象引用  (3)在Client中发送请求,由Service返回结果。  下面看具体的代码如何实现。  3.1 libmyservice代码实现  (1)新建目录frameworks/base/myservice/libservice,进入该目录  view plain  $ cd frameworks/base  $ mkdir myservice  $ cd myservice  $ mkdir libmyservice  $ cd libmyservice  (2)编写libmyservice/myservic.h文件  view plain  #include 《utils/threads.h》    #include 《utils/RefBase.h》    #include 《binder/IInterface.h》    #include 《binder/BpBinder.h》    #include 《binder/Parcel.h》        namespace android {    class MyService : public BBinder    {    mutable Mutex mLock;    int32_t mNextConnId;    public:    static int instantiate();    MyService();    virtual ~MyService();    virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);    };    }; //namespace  (2)编写libservice/myservice.cpp文件  view plain  #include “myservice.h“    #include 《binder/IServiceManager.h》    #include 《binder/IPCThreadState.h》        namespace android {        static struct sigaction oldact;    static pthread_key_t sigbuskey;        int MyService::instantiate()    {    LOGE(“MyService instantiate“);    // defaultServiceManager ()获得ServiceManager的对象引用,addService()可向ServiceManager注册新的服务    int r = defaultServiceManager()-》addService(String16(“android.myservice“), new MyService());    LOGE(“MyService r = %d/n“, r);    return r;    }        MyService::MyService()    {    LOGV(“MyService created“);    mNextConnId = 1;    pthread_key_create(&sigbuskey, NULL);    }        MyService::~MyService()    {    pthread_key_delete(sigbuskey);    LOGV(“MyService destroyed“);    }    // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数,该函数分析接收到的数据包,调用相应的接口函数处理请求    status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)    {    switch(code)    {    case 0: {    pid_t pid = data.readInt32();    int num = data.readInt32();    num = num + 100;    reply-》writeInt32(num);    return NO_ERROR;    }    break;    default:    return BBinder::onTransact(code, data, reply, flags);    }    }    }; //namespace  (3)编写libservice/Android.mk文件  view plain  # File: Android.mk  LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  LOCAL_SRC_FILES := myservice.cpp  LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)  LOCAL_SHARED_LIBRARIES := libutils libbinder  LOCAL_MODULE_TAGS := optional  LOCAL_PRELINK_MODULE := false  LOCAL_MODULE := libmyservice    include $(BUILD_SHARED_LIBRARY)  (4)编译libmyservice.so动态库  在android源码主目录下  view plain  $ source build/envsetup.sh    including device/htc/passion/vendorsetup.sh    including device/samsung/crespo4g/vendorsetup.sh    including device/samsung/crespo/vendorsetup.sh      $ mmm frameworks/base/myservice/libmyservice/  编译成功后生成文件:out/target/product/generic/system/lib/libmyservice.so


声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,谢谢。

上一篇: 外星人x17r2参数(外星人笔记本17r2alienware cpu是4710 8g内存 128g固态➕1t机械硬盘!gtx980m)

下一篇: 什么叫婴幼儿辅食(婴幼儿辅助食品有哪些)



推荐阅读

网站内容来自网络,如有侵权请联系我们,立即删除! | 软文发布 | 粤ICP备2021106084号