Android 面试中Binder必问,是否了解过?

news/2024/11/29 1:38:13/

1.简单介绍下binder

binder是一种进程间通讯的机制

进程间通讯需要了解用户空间内核空间

每个进程拥有自己的独立虚拟机,系统为他们分配的地址空间都是互相隔离的。 如两个进程需要进行通讯,则需要使用到内核空间做载体,内核空间是所有进程共享的一块内存区域。 而用户空间切到内核空间需要使用到系统api ioctl进行通讯。内核获取用户的数据需要使用copy_from_user,内核将数据发送给其他进程需要使用copy_to_user,这两个方法是有性能开销的,对于socket就是使用的这种模式,为了减少这部分的开销,内核提供了binderbinder只需要一次拷贝就可以实现进程通讯.

主要是使用mmap的原理:

内核空间用户空间都开辟一块虚拟内存区域同时指向一块物理地址,这样内核需要传递数据给用户空间时,只需要将数据拷贝到对应的虚拟内存地址中,用户可以通过虚拟内存映射关系,获取到内核中的数据,实现了一次拷贝通讯。

binder架构上面使用的是C/S架构:

binder中有三要素:客户端,服务端和ServiceManager

binder整体过程:

1.注册服务 2.获取服务 3.使用服务

2.Binder的定向制导,如何找到目标Binder,唤起进程或者线程?

数据结构流程:

1.server注册过程 1.server传入一个flat_binder_object给内核态。内核根据这个flat_binder_object创建binder_node节点,为每个进程服务,内部有个binder_proc.proc = server进程2.serviceManager在内核态创建binder_ref引用这个binder_node,内部有一项desc = 1,2,3..,在用户态会创建一个服务链表{name ="server name",handle = "server handle"}
2.client获取服务过程3.client向sm查询服务,传递name4.sm返回handle给驱动程序5.驱动程序在sm的binder_ref_desc红黑树中根据handle找到binder_ref,再根据binder_ref.node找到binder_node,最后给client创建新的binder_ref指向这个binder_node,他的desc从1开始binder_ref{desc=1,node = binder_node},驱动返回desc给client,即handle总结:sm中的handle顺序是根据服务注册顺序显示,返回给client中的handle是根据服务获取的顺序显示的
3.client使用handle过程6.:驱动里面根据handle找到找到binder_ref,根据binder_ref找到binder_node,根据binder_node找到进程server

注:

flat_binder_object{type:是binder实体还是引用,只有需要注册的服务可以传binder实体,其他只能传handle引用flag(联合体)binder(实体:处理函数)/handle(引用:服务的引用):cookie
}

数据传输过程(进程切换):

数据如何复制:

3.Binder中的红黑树,为什么会有两棵binder_ref红黑树

  • refs_by_desc主要是通过desc来查找对应的binder_ref
  • refs_by_node主要是通过node来查找对应的binder_ref

查找方式不一样

4.Binder一次拷贝原理

传统的数据拷贝方式如socket

  • 用户空间---->内核空间:copy_from_user
  • 内核空间---->用户空间:copy_to_user

而binder使用mmap机制

在内核空间和用户空间中间使用物理地址开辟了一个映射关系

内核空间调用copy_from_user会直接将数据拷贝到内核空间并反馈到映射后的物理地址上,由于用户空间和物理地址也有个映射关系,用户空间可以直接通过映射的虚拟地址指针访问到写入物理地址的数据。

这就是binder一次拷贝的原理

5.Binder传输数据的大小限制?

对于内核可以传输的是4M,但是应用层限制在1M-8K范围内,这就是在进程间传输过大的数据会导致崩溃的原因

6.系统服务与bindService等启动的服务的区别

系统服务需要将服务注册到ServiceManager,使用的时候需要通过服务名称去ServiceManger中获取服务的引用,

bindService等启动的服务是将服务注册到AMS中的ServiceMap中,所有的服务的生命周期都由AMS控制。启动服务的进程如果需要使用IPC通讯,都是和获取AMS的代理类进行通讯,AMS也是在SystemServer启动的时候一个注册到ServiceManager的系统服务。

7.Binder多线程

binder线程池默认提供了15个线程进行处理进程间并发事件,如果服务端线程不够用,则驱动会发出一个信号,应用层收到这个信号调用Register_Thread,这样驱动层就可以使用这个新建出来的子线程进行数据的处理

8.Android APP进程天生支持Binder通信的原理是什么?

Android APP进程都是由Zygote进程孵化出来的。 常见场景

点击桌面icon启动APP,或者startActivity启动一个新进程里面的Activity,最终都会由AMS去调用Process.start()方法去向Zygote进程发送请求,让Zygotefork一个新进程,Zygote收到请求后会调用Zygote.forkAndSpecialize()fork出新进程,之后会通过RuntimeInit.nativeZygoteInit来初始化Andriod APP运行需要的一些环境,而binder线程就是在这个时候新建启动的

virtual void onZygoteInit()
{sp proc = ProcessState::self();//启动新binder线程loopproc->startThreadPool();
}

9.同一个线程的请求必定是顺序执行,即使是异步请求(oneway)

一般而言,Client同步阻塞请求Service,直到Service提供完服务后才返回,不过,也有特殊的,比如请求用ONE_WAY方式,这种场景一般主要是用来通知,至于通知被谁消费,是否被消费压根不会关心。 拿ContentService服务为例子,它是一个全局的通知中心,负责转发通知,而且,一般是群发,由于在转发的时候,ContentService被看做Client,如果这个时候采用普通的同步阻塞势必会造成通知的延时发送送,所以这里的Client采用了oneway,异步。


为了帮助大家可以在短时间内有效的恶补 Framework底层中所有知识点,尽快拿到自己想要的Offer。下面整理好了《Framework 知识点汇总手册》相关的学习文档!既能够夯实底层原理、源码解析等核心技术点,又能够掌握普通开发者,难以触及的复杂系统问题设计方案

每个知识点都有左侧导航书签页,看的时候十分方便,由于内容较多篇幅有限,就不一一展示了。读者朋友们可以参考:https://0a.fit/acnLL

《Framework 核心知识点汇总手册》

Handler 机制实现原理部分
1.宏观理论分析与Message源码分析
2.MessageQueue的源码分析
3.Looper的源码分析
4.handler的源码分析
5.总结

Binder 原理

1.学习Binder前必须要了解的知识点
2.ServiceManager中的Binder机制
3.系统服务的注册过程
4.ServiceManager的启动过程
5.系统服务的获取过程
6.Java Binder的初始化
7.Java Binder中系统服务的注册过程

Zygote

  1. Android系统的启动过程及Zygote的启动过程
  2. 应用进程的启动过程

AMS源码分析

  1. Activity生命周期管理
  2. onActivityResult执行过程
  3. AMS中Activity栈管理详解

读者朋友们可以参考:https://0a.fit/acnLL

深入PMS源码

1.PMS的启动过程和执行流程
2.APK的安装和卸载源码分析
3.PMS中intent-filter的匹配架构

WMS
1.WMS的诞生
2.WMS的重要成员和Window的添加过程
3.Window的删除过程

读者朋友们可以参考:https://0a.fit/acnLL


http://www.ppmy.cn/news/1621.html

相关文章

Python 工匠 第三章 容器类型

基础知识 列表常用操作 list(iterable)可以将任何一个可迭代对象转换成列表 >>> from collections.abc import Iterable >>> isinstance("ABC", Iterable) True >>> list("ABC") [A, B, C]>>> chars list("A…

SVM(支持向量机)基本形式推导

据说在dl之前是SVM撑起了ml的半片天,学习后发现SVM是由纯粹的数学推导、转化、求解、优化“堆砌”而来,不如说是数学撑起了ml,ml是数学的学科。以下根据老师ppt上讲解的思路讲讲个人对SVM基本形式推导的理解。 margin(间隔&#x…

Linux——匿名管道、命名管道及进程池概念和实现原理

目录 一.什么是匿名管道 二.如何使用匿名管道 (一).pipe原理 (二).pipe使用 三.命名管道概念及区别 (一).什么是命名管道 (二).与匿名管道的联系和区别 四.命名管道的使用 &…

【Python百日进阶-数据分析】Day124 - Plotly Figure参数:饼图(二)

文章目录metacustomdata 自定义数据domain 域automarginmarker 标记textfont 文字字体textinfo 文本信息direction 方向holehoverlabel 悬停标签insidetextfont 内部文字字体insidetextorientation 内部文本方向outsidetextfont 外部文本字体rotation 旋转scalegroupsort 排序u…

华为机试真题 C++ 实现【连接器问题】【2022.11 Q4新题】

目录 题目 思路 考点 Code 题目 有一组区间[a0,b0],[a1,b1],…(a,b表示起点,终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间; 给定一组连接器[x1,x2,x3,…](x表示连接器的最大可连接长度,即x>=gap),可用于将分离的区间连接起来,但两个…

GIT分布式版本控制系统 | 命令讲解入门

Git概述 Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件;分布式相比于集中式的最大区别在于开发者可以提交到本地&#xff0c…

【免费赠送源码】Springboot喵喵宠物医院管理系统ti5f6计算机毕业设计-课程设计-期末作业-毕设程序代做

【免费赠送源码】Springboot喵喵宠物医院管理系统ti5f6计算机毕业设计-课程设计-期末作业-毕设程序代做 【免费赠送源码】Springboot喵喵宠物医院管理系统ti5f6计算机毕业设计-课程设计-期末作业-毕设程序代做本源码技术栈: 项目架构:B/S架构 开发语言…

[go学习笔记.第十八章.数据结构] 1.基本介绍,稀疏数组,队列(数组实现),链表

一.基本介绍 1.数据结构(算法)的介绍 (1).数据结构是一门研究算法的学科,自从有了编程语言也就有了数据结构,学好数据结构可以编写出更加漂亮,更加有效率的代码 (2).要学习好数据结构就要多多考虑如何将生活中遇到的问题用程序去实现解决 (3).程序&…