当前位置: 首页 > news >正文

Android 面试笔记整理-Binder机制

作者:浪人笔记

面试可能会问到的问题

  1. 从IPC的方式问到Binder的优势
  2. 为什么zygote跟其他服务进程的通讯不使用Binder
  3. Binder线程池和Binder机制

等等这些问题都是基于你对Binder的理解还有对其他IPC通讯的理解

IPC方式有多少种

  • 传统的IPC方式有Socket、共享内存、管道、信号量等
  • 安卓特有的是Binder,其他系统也有自己定义的比如window的wfc(Windows Communication Foundation)

Binder机制的优势

传统的ipc管道跟信号量都是比较轻的,基本不能用于复杂的IPC通讯,Socket有个缺点就是数据要复制两遍,第一遍是进程A复制到Socket通道,第二遍是Socket通道复制到进程B。共享内存的缺点就是不方便管理,如果频繁的对共享内存进行操作很可能会导致死锁、饥饿等问题。

为了解决这个痛点,安卓设计了Binder的通讯机制,提供更高效、安全、可靠的方式。下图是Binder机制图。只需要在内核里面复制一遍,这里可以简单的理解为单例模式,大家都只需要对Binder内存区域做操作,内存只有一份。

还有一些概念,比如我们应该都听说Binder是内核里面的,Binder是怎么用到安卓系统里面的,再看一个图

这里面有四个角色,其实很好理解,两个进程、一个Binder内核空间、一个ServiceManager服务。两个进程时采用的C/S结构一个客户端一个服务端。

  1. Binder内核空间就是一块存在于内核区的内存理解为一个通道

  2. ServiceManager是安卓的核心服务之一,AMS、PMS、WMS这些是一样的。它里面提供了很多线程池。Binder线程池只是其中的一种。在这里可以理解为是管理Binder给外部用的提供了一个注册机制用于识别不同的进程。下面是其他的几个线程池

    • Activity Manager线程池:用于处理Activity启动、停止等操作,保证UI界面的流畅性。
    • JobScheduler线程池:用于调度执行后台任务。
    • MediaServer线程池:用于处理音视频等媒体数据。
    • SurfaceFlinger线程池:用于处理UI界面绘制等操作。

有没有想过为什么要搞那么线程池,还要搞那么多个。其实也比较好理解,因为ServiceManager这个类的有很多地方用到,不可能是单线程处理的,这样就堵塞了。为什么搞那么多线程池是因为不同的功能不同比如有些调用比较频繁有些需要比较多的cpu。只有一个线程池的话很容易会导致占用时间过长等问题。

  1. server进程需要提供方法被别人调用,需要先在ServiceManager里面注册。
  2. server注册完以后会提供接口给client进程调用

来到这里应该可以回答剩下的那两个问题了。

Binder线程池和Binder机制

  • Binder线程池是ServiceManager提供的,利用的是Binder内核机制。
  • Binder机制是安卓为了提供更高效、稳定、可靠的方式实现的一套基于内核的IPC机制。

为什么zygote进程跟其他进程通讯使用socket而不是binder

  1. Binder虽然在内核,但是提供服务的是ServiceManager,这个时候如果要给AMS提供Binder IPC就需要等ServiceManager先初始化好,这个是没办法保证的,如果要保证这个先后顺序又要搞多一套进程通讯就更麻烦了。
  2. 另外,由于Zygote进程只与少数几个进程进行通讯,使用Socket通讯的开销相对较小,因此选择Socket通讯更加合适。而且这里面是优化过的LocalSocket效率会更高。

上面一直说内核空间,那内核空间跟用户空间有什么区别呢?

  1. 内核程序运行在操作系统的内核空间,具有更高的权限和更快的执行速度,能够实现更底层的操作,如硬件驱动、文件系统等,因此通常用于操作系统的核心功能的实现。

  2. 用户程序运行在操作系统的用户空间,具有更多的自由度和可移植性,能够实现更丰富的功能,如应用程序、服务进程等,因此通常用于操作系统的外围功能和应用程序的实现。

简单的说就是内核空间有操作内存的方法,但是这一块对用户空间是封闭的,用户空间里面操作的都是内核提供的服务。比如操作文件用到的文件系统模块和操作内存用到的内存管理模块。拿内存管理模块里面用到的kmallockfree来说。这两个方法在用户空间就调用不到,这是内核封装的方法。

`kmalloc()` 和 `kfree()`: 内核内存分配器,用于在内核空间中动态分配和释放内存。// 这个还并不是c/c++的原生方法,是内核自己封装的

再看一下比如使用Binder的时候我们传的是一个序列化的文件,那他是怎么映射到内存中的?

在内核中有vm_map_ramvm_insert_page这些方法可以把文件插入到内存地址中。而如果在用户空间需要跟这些打交道用到的还是内存管理模块的mmap这些。 mmap 的实现在内核中使用了 vm_area_struct。意思是内存管理模块提供给外面的一层封装。所以与其这么麻烦还不如直接放到内核里面更合适。

这些方法其实都不重要,只需要知道一点,这些方法在用户进程空间是拿不到的


基于Binder的IPC

这里是一些基础,可以不看了。因为这些用的少,方便自己以后看

AIDL

服务端

// IMyService.aidl
interface IMyService {int add(int a, int b);
}// MyService.java
public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}private class MyBinder extends IMyService.Stub {@Overridepublic int add(int a, int b) throws RemoteException {return a + b;}}
}

客户端

// MainActivity.java
public class MainActivity extends AppCompatActivity {private IMyService mService;private ServiceConnection mConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mService = IMyService.Stub.asInterface(service);try {int result = mService.add(1, 2);Toast.makeText(MainActivity.this, "Result: " + result, Toast.LENGTH_SHORT).show();} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {mService = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(this, MyService.class);bindService(intent, mConnection, Context.BIND_AUTO_CREATE);}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(mConnection);}
}

Messager

轻量级的AIDL只能单线程 服务端 MessengerService.java:

public class MessengerService extends Service {private static class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 1:String clientMessage = (String) msg.obj;Log.i("MessengerService", "Received message from client: " + clientMessage);// Send a response back to the clientMessenger clientMessenger = msg.replyTo;Message replyMessage = Message.obtain(null, 2);Bundle bundle = new Bundle();bundle.putString("serverResponse", "Hello from server!");replyMessage.setData(bundle);try {clientMessenger.send(replyMessage);} catch (RemoteException e) {Log.e("MessengerService", "Failed to send message to client", e);}break;default:super.handleMessage(msg);}}}private final Messenger mMessenger = new Messenger(new IncomingHandler());@Overridepublic IBinder onBind(Intent intent) {return mMessenger.getBinder();}
}

客户端 MessengerClient.java:

public class MessengerClient extends AppCompatActivity {private Messenger mMessenger;private static class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 2:String serverMessage = msg.getData().getString("serverResponse");Log.i("MessengerClient", "Received message from server: " + serverMessage);break;default:super.handleMessage(msg);}}}private final Messenger mClientMessenger = new Messenger(new IncomingHandler());@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(this, MessengerService.class);bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(mServiceConnection);}private final ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mMessenger = new Messenger(service);sendMessageToServer();}@Overridepublic void onServiceDisconnected(ComponentName name) {mMessenger = null;}};private void sendMessageToServer() {if (mMessenger == null) {return;}Message message = Message.obtain(null, 1);message.obj = "Hello from client!";message.replyTo = mClientMessenger;try {mMessenger.send(message);} catch (RemoteException e) {Log.e("MessengerClient", "Failed to send message to server", e);}}
}

广播、内容提供者

……

关于Android 面试笔记的真理还有许多知识点在这不能一一的展示,为了方便大家进行复习查阅,这边我整理成了文档的形式了,大家可以进行参考一下:https://qr18.cn/CgxrRy

相关文章:

Android 面试笔记整理-Binder机制

作者:浪人笔记 面试可能会问到的问题 从IPC的方式问到Binder的优势为什么zygote跟其他服务进程的通讯不使用BinderBinder线程池和Binder机制 等等这些问题都是基于你对Binder的理解还有对其他IPC通讯的理解 IPC方式有多少种 传统的IPC方式有Socket、共享内存、管道…...

编程小白的自学笔记十三(python办公自动化读写文件)

系列文章目录 编程小白的自学笔记十二(python爬虫入门四Selenium的使用实例二) 编程小白的自学笔记十一(python爬虫入门三Selenium的使用实例详解) 编程小白的自学笔记十(python爬虫入门二实例代码详解)…...

【Mariadb高可用MHA】

目录 一、概述 1.概念 2.组成 3.特点 4.工作原理 二、案例介绍 1.192.168.42.3 2.192.168.42.4 3.192.168.42.5 4.192.168.42.6 三、实际构建MHA 1.ssh免密登录 1.1 所有节点配置hosts 1.2 192.168.42.3 1.3 192.168.42.4 1.4 192.168.42.5 1.5 192.168.42.6 …...

网络五层协议

应用层(http,https),传输层(udp,tcp),网络层(ip),数据链路层,物理层 什么是http?http 与https 的区别_日晞的博客-CSDN博客 TCP 与UDP 区别_互联网业务udp小包传输_日晞的博客-CSDN博客...

零售行业供应链管理核心KPI指标(一) – 能力、速度、效率和成本

有关零售行业供应链管理KPI指标的综合性分享,涉及到供应链能力、速度、效率和成本总共九大指标,是一个大框架,比较核心也比较综合。 衡量消费品零售企业供应链管理效率和水平的核心KPI通常有哪些? 图片来源-派可数据(…...

MySQL面试题二

1、关系型和非关系型数据库的区别? 关系型数据库的优点 容易理解,因为它采用了关系模型来组织数据。 可以保持数据的一致性。 数据更新的开销比较小。 支持复杂查询(带 where 子句的查询) 非关系型数据库(NOSQL&#x…...

码银送书第五期《互联网广告系统:架构、算法与智能化》

广告平台的建设和完善是一项长期工程。例如,谷歌早于2003年通过收购Applied Semantics开展Google AdSense 项目,而直到20年后的今天,谷歌展示广告平台仍在持续创新和提升。广告平台是负有营收责任的复杂在线平台,对其进行任何改动…...

分布式理论

CAP和BASE CAP C一致性(Consistency) 在分布式环境下,一致性是指数据在多个副本之间能否保持一致性的特征。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致性的状态…...

Excel设置某列或者某行不某行不可以编辑,只读属性

设置单元格只读的三种方式: 1、通过单元格只读按钮,设置为只为 设置行或者列的只读属性,可以设置整行或者整列只读 2、设置单元格编辑控件为标签控件(标签控件不可编辑) 3、通过锁定行,锁定行的修改。锁定的行与只读行的区别在于锁定的行不…...

vue elementui v-for 循环el-table-column 第一列数据变到最后一个

这个动态渲染table表格时发现el-table-column 第一列数据变到最后一个 序号被排到后面 代码 修改后 <el-table:data"tableData"tooltip-effect"dark"style"width: 100%"height"500"><template v-for"(item, index) i…...

宝塔部署阿里云盘webdav

安装Docker 我的系统是CentOS8&#xff0c;如果直接安装会出错&#xff0c;可以看这篇文章&#xff1a;Failed to download metadata for repo ‘appstream‘ docker 国内镜像&#xff1a; http://hub-mirror.c.163.com/下载镜像 宝塔安装docker管理器&#xff0c;然后搜索…...

Ceph分布式存储系统优化分析

Ceph支持多种存储访问接口&#xff0c;现有的多种性能测试工具都可用于Ceph的性能测试&#xff0c;如测试块接口性能的fio&#xff0c;iometer等&#xff1b;测试CephFS接口的filebench&#xff0c;fio等;测试对象接口的cosbench等。Ceph有专用的基准测试集CBT&#xff0c;其包…...

supOS APP开发者课程练习册创建服务(命名:getPropertiesHistory)

创建服务&#xff08;命名&#xff1a;getPropertiesHistory&#xff09;,调用getPropertiesHistory()服务&#xff0c;获取“催化裂化一车间”对象的“重质馏分油_进”最近5分钟内的历史值&#xff0c;每一分钟取一个值&#xff0c;开始时间和结束时间需要调用时间格式化功能集…...

认识excel篇3之数据的有效性(数据验证)

数据有效性不仅能够对单元格的输入数据进行条件限制&#xff0c;还可以在单元格中创建下拉列表菜单方便用户选择输入。如果没有做数据验证&#xff0c;单元格内默认可以输入任意类型的数据。数据验证就是限制单元格输入数据&#xff08;必须输入符合要求的才能输入&#xff09;…...

adb 命令行执行单元测试

文章目录 1、配置 adb 环境变量2、adb 执行测试3、官方文档解读 adb 使用&#xff08;1&#xff09;第一条执行测试的adb命令&#xff08;2&#xff09;am instrument 参数&#xff08;3&#xff09;-e 参数 的 key-value键值对&#xff08;4&#xff09;用法用例 4、存在问题 …...

Ceph入门到精通-Linux下Ceph源码编译和GDB调试

Ceph版本&#xff1a;14.2.22 Linux版本&#xff1a;ubuntu-server 18.04 第一部分 下载Ceph源码 1.1 配置Ceph源码镜像源 Ceph源码是托管在Github上&#xff0c;由于某些原因&#xff0c;国内访问Github网站很慢&#xff0c;所以需要从其他途径加速获取源码。Github官方给出…...

【c语言】动态内存管理(超详细)

他治愈了身边所有人&#xff0c;唯独没有治愈他自己—超脱 csdn上的朋友你们好呀&#xff01;&#xff01;今天给大家分享的是动态内存管理 &#x1f440;为什么存在动态内存分配 我们定义的局部变量在栈区创建 int n 4;//在栈上开辟4个字节大小int arr[10] { 0 };//在栈上开…...

Linux/centos上如何配置管理NFS服务器?

Linux/centos上如何配置管理NFS服务器&#xff1f; 1 NFS基础了解1.1 NFS概述1.2 NFS工作流程 2 安装和启动NFS服务2.1 安装NFS服务器2.2 启动NFS服务 3 配置NFS服务器和客户端3.1 配置NFS服务器3.2 配置NFS客户端 4 实际示例4.1 基本要求4.2 案例实现 1 NFS基础了解 NFS&…...

Element组件浅尝辄止5:Empty 空状态组件

Empty空状态组件&#xff1a;空状态时的占位提示。 如第一次进入当前功能模块时&#xff0c;数据状态为空&#xff0c;则展示空状态&#xff0c;可用到Empty组件 1.How? <el-empty description"描述文字"></el-empty> 2.自定义图片 通过设置 image 属…...

【华为Datacom 综合拓扑案例—分享篇】

拓扑图 题目要求 实验要求&#xff1a; 1、PC1\PC2\PC3\PC4采用DHCP自动获取IP地址&#xff0c;SW5作为服务器&#xff0c;SW3和SW4作为中继 创建地址池ip pool huawei1和ip pool huawei2&#xff0c;租期都为2天 2、SW3与SW4做链路聚合&#xff0c;采用LACP模式。SW3作为主…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...