首页 > 其他分享 >Android Binder机制简述

Android Binder机制简述

时间:2023-11-13 18:32:48浏览次数:41  
标签:Binder 计数 简述 引用 进程 Android 共享内存

Binder机制是Android系统提供的一种高级IPC机制,它使用代理对象、共享内存和序列化等技术,实现了进程间通信和远程调用的功能。它允许在不同进程之间进行数据传输和方法调用,实现了进程间的解耦。在Android系统中,Binder被广泛应用于各种组件之间的通信,例如Activity与Service、Service与Service、应用与系统服务等。

Binder的概念如下:

  1. 驱动层:Binder作为一个设备驱动存在于Linux内核中。当应用程序与Binder对象进行通信时,实际上是在与Binder驱动进行交互。Binder驱动负责管理Binder对象、传输数据以及进程间的上下文切换等工作。设备文件节点通常是 /dev/binder

不过,在某些版本的Android中,您可能会看到其他设备文件节点,如 /dev/hwbinder 和 /dev/vndbinder。这些设备节点都是用于Binder驱动的不同实例,分别用于硬件抽象层(HAL)和供应商模块之间的通信。

  1. 用户空间库:Binder提供了一套C++库和Java库,以方便用户空间的应用程序使用。这些库包括序列化/反序列化数据的工具、用于管理Binder对象的引用计数的工具以及在进程间调用方法时的代理和存根对象等。在Java层,通常使用AIDL(Android Interface Definition Language)来定义跨进程接口。
  2. 代理与存根:Binder机制使用了代理(Proxy)和存根(Stub)对象来实现进程间的方法调用。当一个进程要调用另一个进程中的方法时,它会通过代理对象将方法调用转换为一个Binder事务。然后,这个事务会被发送到接收进程,由存根对象解析并执行对应的方法。最后,存根对象将结果返回给代理对象,完成整个跨进程调用。
  3. 序列化与反序列化:在进程间传输数据时,需要将数据序列化为字节流,以便在不同进程之间进行传输。在接收进程中,数据会被反序列化为原始格式。Binder提供了一套序列化和反序列化的工具(如Parcel类),用于在进程间传输数据。
  4. 引用计数与死亡通知:Binder机制通过引用计数来管理Binder对象的生命周期。当一个进程获得了另一个进程的Binder对象引用时,引用计数会增加。当引用计数减少到零时,Binder对象会被销毁。另外,Binder还支持死亡通知机制,允许一个进程监听另一个进程的Binder对象死亡事件。

实现原理

Binder IPC(进程间通信)机制在数据传输过程中使用了一种称为"引用计数的内存映射"(reference-counted memory mapping)技术。这种技术通过共享内存来减少数据在发送方和接收方之间的复制操作。

在Binder IPC传输过程中,以下步骤涉及到引用计数的内存映射技术:

  1. 发送方进程(客户端)将要传输的数据写入其本地内存。这些数据可能包括原始数据、文件描述符、Binder对象等。
  2. Binder驱动程序在发送方进程和接收方进程(服务端)之间建立一块共享内存区域。这个共享内存区域的引用计数被设置为1。
  3. 发送方进程将数据复制到共享内存区域,并将数据的内存地址和大小传递给Binder驱动程序。
  4. Binder驱动程序将共享内存区域的引用计数增加1,然后将共享内存区域的地址和大小传递给接收方进程。
  5. 接收方进程通过映射共享内存区域来访问数据。此时,共享内存区域的引用计数仍为2。
  6. 当发送方和接收方进程都不再需要这些数据时,它们分别告知Binder驱动程序。驱动程序随后将共享内存区域的引用计数减1。当引用计数降至0时,驱动程序释放共享内存区域。

通过这种引用计数的内存映射技术,Binder IPC可以将数据在进程间的复制操作降至最低,从而提高IPC性能。然而,这种方法并不适用于所有场景。在某些情况下,例如当数据量很小或者不同安全上下文之间的通信时,Binder仍然可能使用传统的数据复制方法。

ServiceManager

ServiceManager在系统启动过程中的初始化非常重要,因为它是Android系统服务管理的核心组件,需要在其他服务启动之前就准备就绪,以便随后可以注册和查找其他系统服务。

  1. Native层的ServiceManager是在Android系统启动阶段初始化的。在Android系统启动过程中,会执行一个名为init的程序,它负责启动和初始化系统中的各个组件和服务。在init程序执行过程中,会调用ServiceManager的main函数,从而启动并初始化Native层的ServiceManager。这样,ServiceManager就可以接收和处理来自其他进程的服务注册和查询请求。
  2. Java层的ServiceManager(位于Java层):它是一个Java类,提供了在Java层注册和获取系统服务的功能。它通过JNI(Java Native Interface)与Native层的ServiceManager进行通信,从而实现对系统服务的查询和注册。 当Java层的ServiceManager需要注册或查找一个系统服务时,它会通过JNI调用Native层的ServiceManager的相应方法。同样,当Native层的ServiceManager收到服务注册或查询请求时,会在其内部映射表中进行查找或添加相应的服务。

相关

  1. 为何System server请求zygote创建进程时用的是socket通讯而不是binder? 可能是因为此处socket完全满足需求, 简单又高效, 并不是binder此时不可用. 因为servicemanager先于System server启动了
  2. 为什么Intent不能传递大数据?
  • 性能:将大量数据附加到 Intent 可能导致性能下降。Intent 对象在进程之间传递时,实际上是通过 Binder IPC 机制进行的。如果传递的数据量过大,可能会导致 Binder 传输缓冲区的填充和性能下降。
  • 限制:Binder 事务缓冲区的大小有限。根据 Android 版本和设备的不同,限制可能在 1MB 左右。如果超出这个大小限制,可能会抛出 TransactionTooLargeException 异常。
  • 解决方案: 文件, 共享内存, content provider
  1. 相对于其他linux ipc机制, binder有什么优势?
  • . 更高效的数据传输:Binder采用一次内存复制策略,而其他IPC机制如管道、消息队列等通常需要至少两次内存复制。这使得Binder在数据传输方面更加高效。
  • . 强类型:Binder基于接口定义语言(IDL),允许定义强类型的接口。这有助于确保数据在进程间传输时具有正确的类型和结构,从而减少潜在的类型错误和程序崩溃。
  • . 引用计数和生命周期管理:Binder内建了引用计数和对象生命周期管理机制。当一个Binder对象不再被任何进程引用时,它会自动被销毁。这有助于避免内存泄漏和资源浪费。
  • . 安全性:Binder提供了基于UID(User Identifier)的权限控制机制,允许对进程间通信进行访问控制。这有助于确保只有具备适当权限的进程才能访问特定的服务和资源。
  1. 结构简单,易于使用:Binder提供了一个简洁的API,使得开发者能够轻松地实现跨进程通信。在Android中,Binder机制被高度集成,使得开发者能够无缝地在应用程序中使用服务和组件。
  • . 适应性:Binder机制在Android系统中得到了广泛应用,支持跨平台和多种设备类型,具有很高的适应性。这使得Android设备和应用程序能够在各种不同场景中实现高效的进程间通信。

标签:Binder,计数,简述,引用,进程,Android,共享内存
From: https://blog.51cto.com/u_16175630/8351440

相关文章

  • Unity Android Studio 设置自启动应用
    前言最近有需求,需把Unity软件发布到android平台后开机启动应用,在网上查了很多资料,现整理如下Unity部分新建项目,平台设置为android tips:需要勾选ExportProject以便于导入AndroidStudio,使用Unity版本为2021.3.32f1AndroidStudio部分 androidstudio......
  • 在Android Studio中如何从MySQL数据库中展示项目中的数据?
    要在AndroidStudio中从MySQL数据库展示项目中的数据,你需要遵循以下步骤:1.添加MySQLConnector/J依赖项到你的项目的build.gradle文件中:```groovydependencies{implementation'mysql:mysql-connector-java:8.0.23'}```2.在AndroidManifest.xml文件中添加INTERNET......
  • 三年Android开发怒怼某大厂HR,怒刷1549页面试题科大上岸
    最近,有个读者联系了我和我诉说了最近他面试碰到的一件很气愤的事情。为什么方便就称呼小华了。小华目前是三年Android开发,从上个月就开始一直在找工作,因为今年的大环境不好,面试的时候也是处处碰壁,面一家挂一家,面完之后怀疑自我,是不是自己真的太菜了找不到工作。但是也没有气馁多久,......
  • Android并发编程高级面试题汇总(含详细解析 二)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • Android 文件绝对路径和Content开头的Uri互相转换
    最近在做一个项目时,需要做一个九宫格选择图片上传的功能,最后拿到的图片地址是文件的绝对路径地址,我需要的是Content开头的Uri,所以需要做一个转换查阅资料找到如下方法,代码如下://路径文件转成URIpublicstaticUrigetImageContentUri(Contextcontext,java.io.FileimageFile)......
  • android读取asset文件下的内容
    要获取assets文件夹中的文件,可以使用下面几种方法:1.使用AssetManager类:通过调用Context的getAssets()方法获取AssetManager对象,然后使用该对象打开并读取文件。//获取AssetManager对象AssetManagerassetManager=getContext().getAssets();//打开并读取文件InputStream......
  • Android自定义View使用系统自有属性
    原文链接:Android自定义View使用系统自有属性-Stars-One的杂货小窝本篇默认各位有自定义View的相关知识,本篇只作为一个小知识点补充有这样一种情况,比如说我们的一个自定义View中有个maxLines的属性,但是我们会注意到这个maxLines其实Android里面已经存在了(如TextView中),我们能......
  • Android:在按钮(Button)或图像按钮(ImageButton)上合并文本和图片。
    内容来自DOChttps://q.houxu6.top/?s=Android:在按钮(Button)或图像按钮(ImageButton)上合并文本和图片。我正在尝试在按钮背景上添加一张图片,并根据运行时发生的情况动态地添加一些文本到图片上方。如果使用ImageButton,我甚至无法添加文本。如果使用Button,我可以添加文本,但只......
  • android Handler应用
    android在运行时改变ui需要在ui线程中修改才行,不然就会报错或者无法启动应用。我们怎么可以做事不管呢?既然不能在ui线程外的地方运行修改ui的代码,我们可以用Handler解决这个问题,而Handler消息机制用于同进程的线程间通信,通过发送Message我们可以有效的避开报错。那怎么写Handl......
  • android ProgressBar样式
    **实现进度条由浅黄(#ffff33)到深黄色(#ff6600)的渐变样式。****与进度条自动从0加载到99,进度条每次加1**-`android:max`:进度条的最大值。-`android:progressDrawable`:设置轨道对应的`Drawable`对象。-style="@android:style/Widget.ProgressBar.Horizontal"设置**水平进度条*......