华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装

什么是 Binder?

Binder 是 Android 系统中进程间通讯(IPC)的一种办法,也是 Android 系统中最重要的特性之一。Android 中的四大组件 Activity,Service,Broadcast,ContentProvider,不同的 App 等都运转在不同的进程中,它是这些进程间通讯的桥梁。正如其名“粘合剂”相同,它把系统中各个组件粘合到了一同,是各个组件的桥梁。

了解 Binder 关于了解整个 Android 系统有着非常重要的效果,假如对 Binder 不了解,就很难对 Android 系统机制有更深化的了解。

1. Binder 架构

  • Binder 通讯选用 C/S 架构,从组件视角来说,包括 Client、 Server、 ServiceManager 以及 Binder 驱动,其间 ServiceManager 用于办理系统中的各种服务。
  • Binder 在 framework 层进行了封装,经过 JNI 技能调用 Native(C/C++)层的 Binder 架构。
  • Binder 在 Native 层以 ioctl 的办法与 Binder 驱动通讯。

2. Binder 机制

  • 首要需求注册服务端,只要注册了服务端,客户端才有通讯的方针,服务端经过 ServiceManager 注册服务,注册的进程便是向 Binder 驱动的大局链表 binder_procs 中刺进服务端的信息(binder_proc 结构体,每个 binder_proc 结构体中都有 todo 使命行列),然后向 ServiceManager 的 svcinfo 列表中缓存一下注册的服务。
  • 有了服务端,客户端就能够跟服务端通讯了,通讯之前需求先获取到服务,拿到服务的署理,也能够了解为引证。比方下面的代码: //获取WindowManager服务引证WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE); 获取服务端的办法便是经过 Se华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装rviceManager 向 svcinfo 列表中查询一下回来服务端的署理,svcinfo 列表便是全部已注册服务华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装的通讯录,保存了全部注册的服务信息。
  • 有了服务端的引证咱们就能够向服务端发送恳求了,经过 BinderProxy 将咱们的恳求参数发送给 ServiceMana华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装ger,经过同享内存的办法运用内核办法 copy_from_user() 将咱们的参数先复制到内核空间,这时咱们的客户端进入等候状况,然后 Binder 驱意向服务端的 todo 行列里边刺进一条业务,履行完之后把履行成果经过 copy_to_user() 将内核的成果复制到用户空间(这儿仅仅履行了复制指令,并没有复制数据,binder只进行一次复制),唤醒等候的客户端并把成果呼应回来,这样就完结了一次通讯。

怎样样是不是很简略,以上便是 Binder 机制的首要通讯办法,下面咱们来看看具体完结。

3. Binder 驱动

咱们先来了解下用户空间与内核空间是怎样交互的。

先了解一些概念

用户空间/内核空间

具体解说能够参阅 Kernel Space Definition;简略了解如下:

Kernel space 是 Linux 内核的运转空间,User space 是用户程序的运转空间。为了安全,它们是阻隔的,即运用户的程序溃散了,内核也不受影响。

Kernel space 能够履行恣意指令,调用系统的全部资源;User space 只能履行简略的运算,不能直接调用系统资源,有必要经过系统接口(又称 system call),华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装才干向内核宣布指令。

系统调用/内核态/用户态

虽然从逻辑上抽离出用户空间和内核空间;可是不可避免的的是,总有那么一些用户空间需求拜访内核的资源;比方应用程序拜访文件,网络是很常见的作业,怎样办呢?

Kernel space can be accessed by user processes only through the use of system calls.

用户空间拜访内核空间的仅有办法便是系统调用;经过这个一致进口接口,全部的资源拜访都是在内核的操控下履行,避免导致对用户程序对系统资源的越权拜访,然后确保了系统的安全和安稳。用户软件良莠不齐,要是它们乱搞把系统玩坏了怎样办?因而关于某些特权操作有必要交给安全可靠的内核来履行。

当一个使命(进程)履行系统调用而堕入内核代码中履行时,咱们就称进程处于内核运转态(或简称为内核态)此刻处理器处于特权级最高的(0级)内核代码中履行。当进程在履行用户自己的代码时,则称其处于用户运转态(用户态)。即此刻处理器在特权级最低的(3级)用户代码中运转。处理器在特权等级高的时分才干履行那些特权CPU指令。

内核模块/驱动

经过系统调用,用户空间能够拜访内核空间,那么假如一个用户空间想与别的一个用户空间进行通讯怎样办呢?很天然想到的是让操作系统内核增加支撑;传统的 Linux 通讯机制,比方 Socket,管道等都是内核支撑的;可是 Binder 并不是 Linux 内核的一部分,它是怎样做到拜访内核空间的呢?Linux 的动态可加载内核模块(Loadable Kernel Module,LKM)机制处理了这个问题;模块是具有独立功用的程序,它能够被独自编译,但不能独立运转。它在运转时被链接到内核作为内核的一部分在内核空间运转。这样,Android系统能够经过增加一个内核模块运转在内核空间,用户进程之间的经过这个模块作为桥梁,就可华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装以完结通讯了。

在 Android 系统中,这个运转在内核空间的,担任各个用户进程经过 Binder 通讯的内核模块叫做 Binder 驱动;

驱动程序一般指的是设备驱动程序(Device Driver),是一种能够使计算机和设备通讯的特别程华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装序。相当于硬件的接口,操作系统只要经过这个接口,才干操控硬件设备的作业;

驱动便是操作硬件的接口,为了支撑 Binder 通讯进程,Binder 运用了一种“硬件”,因而这个模块被称之为驱动。

了解了上面这些概念,咱们再来看下上面的图,用户空间中 binder_ope标签3n(), bind标签1er_mmap(), binder_ioctl() 这些办法经过 system call 来调用内核空间 Binder 驱动中的办法。内核空间与用户空间同享内存经过 copy_from_user(), copy_to_user() 内核办法来完结用户空间与内核空间内存的数据传输。Binder驱动中有一个大局的 binder_procs 链表保存了服务端的进程信息。

4. Binder 进程与线程

关于底层Binder驱动,经过 binder_procs 链表记载全部创立的 binder_proc 结构体,binder 驱动层的每一个 binder_proc 结构体都与用户空间的一个用于 bi标签3nder 通讯的进程一一对应,且每个进程有且只要一个 ProcessState 目标,这是经过单例形式来确保的。在每个进程中能够有很多个线程,每个线程对应一个 IPCThreadState 目标,IPCThreadState 目标也是单例形式,即一个线程对应一个 IPCThreadState 目标,在 Binder 驱动层也有与之相对应的结构,那便是 Binder_thread 结构体。在 binder_proc 结构体中经过成员变量 rb_root threads,来记载当时进程内全部的 binder_thread。

Binder 线程池:每个 Server 进程在发动时创立一个 binder 线程池,并向其间注册一个 Binder 线程;之后 Server 进程也能够向 binder 线程池注册新的线程,或许 Binder 驱动在探测到没有闲暇 binder 线程时主意向 Server 进程注册新的的 binder 线程。关于一个 Server 进程有一个最大 Binder 线程数约束,默以为16个 binder 线程,例如 Android 的 system_server 进程就存在16个线程。关于全部 Client 端进程的 binder 恳求都是交由 Server 端进程的 binder 线程来处理的。

5. ServiceManager 发动

了解了 Binder 驱动,怎样与 Binder 驱动进行通讯呢?那便是经过 ServiceManager,很多文章称 ServiceManager 是 Binder 驱动的看护进程,大管家,其实 ServiceManager 的效果很简略便是供给了查询服务和注册服务的功用。下面咱们来看一下 ServiceManager 发动的进程。

  • ServiceManager 分为 framework 层和 native 层,framework 层仅仅对 native 层进行了封装便利调用,图上展现的是 native 层的 Servic标签17eManager 发动进程。
  • ServiceManager标签11 的发动是系统在开机时,init 进程解析 init.rc 文件调用 service_manager.c 中的 main() 办法进口发动的。native 层有一个 binder.c 封装了一些与 Binder 驱动交互的办法。
  • ServiceManager 的发动分为三步,首要翻开驱动创立大局链表 binder_procs,然后将自己当时进程信息保存到 binder_procs 链表,最终打开 loop 不断华为云-万搏直播app安卓 -万搏直播app-万搏直播app下载安装的处理同享内存中的数据,并处理 BR_xxx 指令(ioctl 的指令,BR 能够了解为 binder reply 驱动处理完的呼应)。

6. ServiceManager 注册服务

  • 注册 MediaPlayerService 服务端,咱们经过 ServiceManager 的 addService() 办法来注册服务。
  • 首要 ServiceManager 向 Binder 驱动发送 BC_TRANSACTION 指令(ioct标签3l 的指令,BC 能够了解为 binder client 客户端发过来的恳求指令)带着 ADD_SERVICE_TRANSACTION 指令,一起注册服务的线程进入等候状况 waitForResponse()。Binder 驱动收到恳求指令向 ServiceManager 的 todo 行列里边增加一条注册服务的业务。业务的使命便是创立服务端进程 binder_node 信息并刺进到 binder_procs 链表中。
  • 业务处理完之后发送 BR_TRANSACTION 指令,ServiceManager 收到指令后向 svcinfo 列表中增加现已注册的服务。最终发送 BR_REPLY 指令唤醒等候的线程,告诉注册标签11成功。

7. ServiceManager 获取服务

  • 获取服务的进程与注册相似,相反的进程。经过 ServiceManager 的 getService() 办法来注册服务。
  • 首要 ServiceManager 向 Binder 驱动发送 BC_TRANSACTION 指令带着 CHECK_SERVICE_TRANSACTION 指令,一起获取服务的线程进入等候状况 waitForResponse()。
  • Binder 驱动收到恳求指令向 ServiceManager 的发送 BC_标签14TRANSACTION 查询已注册的服务,查询到直接呼应 BR_REPLY 唤醒等候的线程。若查询不到将与 binder_procs 链表中的服务进行一次通讯再呼应标签17。

8. 进行一次完好通讯

  • 咱们在运用 Binder 时根本都是调用 framework 层封装好的办法,AIDL 便是 framework 层供给的傻瓜式是运用办法。假定服务现已注册完,咱们来看看客户端怎样履行服务端的办法。
  • 首要咱们经过 ServiceManager 获取到服务端的 BinderProxy 署理目标,经过调用 BinderProxy 将参数,办法标识(例如:TRANSA标签1CTION_test,AIDL中主动生成)传给 ServiceManager,一起客户端线程进入等候状况。
  • ServiceManager 将用户空间的参数等恳求数据复制到内核空间,并向服务端刺进一条履行履行办法的业务。业务履行完告诉 ServiceManager 将履行成果从内核空间复制到用户空间,并唤醒等候的线程,呼应成果,通讯完毕。

总结

好了,这儿仅仅从完结逻辑上简略介绍了下 Bind标签3er 机制的作业原理,想要深化了解 Binder 机制,还得自己下功夫,看源码,虽然这个进程很苦楚。一遍看不懂就再来一遍,说实话自己了解能力比较差,跟着博客思路看了不下十遍。尽力总会有收成,好好赏识 native 层各办法之间花式跳转的魅力吧。最终你将发现新世界的大门在向你打开。

今年金九银十我花一个月的时刻录入收拾了一套常识系统,假如有主意深化的系统化的去学习的,能够私信我【安卓】,我会把我录入收拾的材料都送给我们,协助我们更快的进阶。

重要的事说三遍,转发+转发+转发,让更多需求的朋友们都能够看到而且领到!

Write a Comment

电子邮件地址不会被公开。 必填项已用 *标注