Android系统面经(1/20)深入解析Binder

牛客高级系列专栏:

安卓(安卓系统开发也要掌握)


嵌入式


  • 本人是2020年毕业于广东工业大学研究生:许乔丹,有国内大厂CVTE和世界500强企业安卓开发经验,该专栏整理本人从嵌入式Linux转Android系统开发过程中对常见安卓系统开发面试题的理解;
  • 1份外卖价格助您提高安卓面试准备效率,为您面试保驾护航!!

正文开始⬇

Binder在日常开发经常会用到,毕竟是Android跨进程方法的不二之选。Binder的源码实现逻辑很复杂,本文主要是介绍Binder在面试时可能被Q到的问题,挖Bidner源码的大神可绕道,面试官可能会问:

  • 请介绍什么是Binder机制 ⭐⭐⭐⭐
  • 请介绍Binder机制流程 ⭐⭐⭐⭐
  • Binder有什么优势?(字节跳动)⭐⭐⭐⭐⭐
  • Binder机制需要多少次内存拷贝 ⭐⭐⭐
  • Binder是如何做到一次拷贝?(腾讯) ⭐⭐⭐
  • Android有很多跨进程通信方法,为何选择Binder?⭐⭐⭐
  • MMAP的原理讲解(腾讯)⭐⭐
  • Binder机制是如何跨进程的(阿里)⭐⭐⭐
  • 描述AIDL生成的java类细节(字节跳动)⭐⭐⭐
  • 为什么Intent不能传递大数据(阿里)⭐⭐⭐

看完以下的解析,一定可以让面试官眼前一亮。

目录

    1. Binder是什么
    • 1.1 Android中的跨进程通讯方法
    1. 为何要使用Binder
    • 2.1 传统的Linux跨进程通讯 2.1.1 背景知识
    1. Bind的通讯原理
    • 3.1 了解Binder通讯原理需要知道两个概念
    • 3.2 Binder的通讯原理
    • 3.3 Binder有什么优势
    • 3.4 Binder机制是如何跨进程通讯的?
    • 3.5 Binder传输数据的大小限制
    1. Binder通讯模型
    • 4.1服务端、客户端、ServiceManager、Binder驱动
      • 4.1.1 Binder驱动
      • 4.1.2 ServiceManager
    • 4.2 使用Binder进行数据传输的具体过程
      • 4.2.1 服务端向ServiceManager注册
      • 4.2.2 客户端获取服务端Binder引用
      • 4.2.3 使用服务
    • 4.3 Binder通讯中的代理模式
    • 4.4 好多Binder分不清?
    • 4.5 Binder源码分析
  • 参考文档

1份外卖价格助您提高安卓面试准备效率,为您面试保驾护航!!

1.Binder是什么

Binder是Android系统提供的一种IPC(进程间通信)机制,采用C/S(客户端与服务端结构)架构。Binder原理是掌握Android系统的基石,Binder就像Android中的血管,基本上贯穿了andorid框架层的全部。在Android中我们所使用的Activity,Service等组件都需要和AMS(system_server)通信,这种跨进程的通信都是通过Binder完成。 在基于Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务(Service)。Client、Server和ServiceManager这三者之间的交互关系如下图所示:

关键点

  • 从进程间通信的角度看,Binder 是一种进程间通信的机制。
  • 从 Server 进程的角度看,Binder 指的是 Server 中的 Binder 实体对象(Binder类 IBinder)。
  • 从 Client 进程的角度看,Binder 指的是对 Binder 代理对象,是 Binder 实体对象的一个远程代理。
  • 从传输过程的角度看,Binder 是一个可以跨进程传输的对象;Binder 驱动会自动完成代理对象和本地对象之间的转换。
  • 从Android Framework角度看,Binder是ServiceManager连接各种Manager和相应ManagerService的桥梁 Binder跨进程通信机制:基于C/S架构,由Client、Server、ServerManager和Binder驱动组成。

进程空间分为用户空间和内核空间。用户空间不可以进行数据交互;内核空间可以进行数据交互,所有进程共用一个内核空间。Client、Server、ServiceManager均在用户空间中实现,而Binder驱动程序则是在内核空间中实现的。

1.1 Android中的跨进程通讯方法

  • 共享内存:通过共享缓冲区直接映射到各个进程的虚拟地址空间,速度快。但实现比较复杂,进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决。
  • 消息队列:提供了一种从一个进程向另一个进程发送一个数据块的方法,但需要进行2次数据拷贝,不适合频繁或者数据量大的情况。
  • 管道:分为有名/无名管道,在创建时分配一个page大小的内存,缓存区大小比较有限。
  • 信号量:一般作为一种锁机制,用于进程/线程同步。
  • 信号:更适合作为进程中断控制,而非数据交换。
  • Socket/LocalSocket:允许位于同一主机(计算机)或使用网络连接起来的不同主机上的应用程序之间交换数据;
  • Binder: Binder是Android中的一种跨进程通信机制;
  • 匿名共享内存:在Android系统中,提供了独特的匿名共享内存子系统Ashmem(Anonymous Shared Memory),它利用了Linux的 tmpfs文件系统(一种可以基于RAM或是SWAP的高速文件系统)来实现不同进程间的内存共享。有两个特点:能够辅助内存管理系统来有效地管理不再使用的内存块; ○通过Binder进程间通信机制来实现进程间的内存共享;
  • File:两个进程通过读写同一个文件来进行数据共享,共享的文件可以是文本、XML、JOSN。文件共享适用于对数据同步要求不高的进程间通信。通过文件进行多进程通信用法简单,但不适合高并发情况
  • ContentProvider: Android四大组件之一,常用于进程间数据共享,特别是一对多的情况,不过受限于AIDL;
  • Bundle:Bundle实现了Parcelable接口,所以它可以方便的在不同的进程间传输。Acitivity、Service、Receiver都是在Intent中通过Bundle来进行数据传递。Bundle很常见也很常用,但只能传输Bundle支持的数据类型,同样不适合大量数据的传输; 面试官很喜欢问Android中有哪些跨进程方法,如果你可以答出这么多,一定可以加分

2.为何要使用Binder

众所周知,Android系统基于Linux系统,因此Linux系统使用的IPC方法:共享内存、消息队列、管道、信号量等,在Android系统上也都能使用。1.1小节就列出了10+种方法,那么为何还需要Binder? 使用Binder的理由可以归纳为:性能、安全、稳定、语言四个方面:

  • 性能:管道、消息队列、Socket都需要2次数据拷贝(即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区),而Binder只要1次(可见第3节分析),且Binder相对Socket方法也更加高效, Socket主要用于跨网络的进程间通讯,传输的效率比较低。当然共享内存1次数据拷都不需要,因此就性能而言,共享内存高于Binder;
  • 安全:Android系统为每个应用都分配各自的UID/PID来验证身份,保证了进程通信的安全性;
  • 稳定:共享内存1次数据拷贝都不需要,但实现的方法比较复杂,并且需要做好进务端同步,容易出现死锁或者资源竞争,稳定性差。而Binder基于C/S架构,客户端和服务端彼此独立,稳定性强。
  • 语言:Linux是基于C语言,C语言是面向过程的,Android应用层和Java Framework是基于Java语言,Java语言是面向对象的。Binder本身符合面向对象的思想,因此作为Androißd的通信机制更合适不过。 因此,在Android系统的IPC方式,一般情况下都推荐使用Binder。当然,在Android源码里,上述其他IPC方法也会使用到。接下来让我们先看看传统的Linux跨进程通讯原理。

2.1 传统的Linux跨进程通讯

2.1.1 背景知识

进程空间分为用户空间和内核空间。用户空间是用户程序代码运行的地方,内核空间是内核代码运行的地方。为了安全,它们是隔离的,这样即使用户程序奔溃了,内核也不受影响。

Android是基于Linux的,以32位系统来说,每个Linux进程都有3G虚拟内存空间,称之为用户空间,以及1G的内核空间。其中,不同进程的用户空间是相互隔离的,不可直接通讯;但是内核空间却是共享的。以讲程A发送数据到进程B为例,需要经历如下步骤:

  • A进程的内核空间开辟一块内核缓存区,通过copy_

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Android系统面试题全解析 文章被收录于专栏

2020年研究生毕业后,工作重心由嵌入式Linux转为安卓系统,Android发展已经很多年,网上面向中初级Android系统开发的面经还比较少,也不够集中,因此梳理出本专栏,本专栏收集了本人工作中持续积累的众多安卓系统知识,持续更新中。

全部评论
有个疑问,发送进程通过 copy_to_user()将数据拷贝到 内核缓存区,为啥binder创建的接受缓存区跟接收进程的客户空间直接是映射?从上图看前后都是 客户空间跟内核空间的交互,发送进程的用户空间跟 内核空间为啥不存在映射?
点赞 回复 分享
发布于 2023-08-19 22:11 湖北
安卓面试技巧
点赞 回复 分享
发布于 2023-02-21 09:24 天津
案例分析更好理解了
点赞 回复 分享
发布于 2023-02-21 09:03 江苏

相关推荐

0.直接问是不是叫xxx,没有让自我介绍,哈哈主播还准备了呢1.问项目是什么?是否是从0到1自己实现的?Android端是自己从0到1实现的,后端是网上开源的,调的其他人的接口。2.项目中写了 采用 MVVM架构 功能迭代速度提高了百分之xxx,使用 Kotlin 减少了百分之xxx的时间成本 这些数据是如何得到的?对比之前写的MVP项目所用的时间得到的,编写MVVM项目所用的时间实际上是比第一个短的3.使用 Kotlin 降低的代码重复率是如何得到的?Kotlin的语***比java简单很多,代码量也会比较少4.我看你简历里写了内存泄漏,你是如何检测内存泄漏的?使用AS自带的内存泄漏检测工具5.这个工具是如何检测到内存泄漏的,具体的原理是什么?主播答了垃圾回收机制的一些东西,好像毫不相干...根部搜索法,从根部开始搜索对象引用链,没找到的对象就是可以回收的对象(应该还要说,如果对象可以被回收却没有回收,就是发生了内存泄漏?)6.内存泄漏的原理是什么?长生命周期对象持有短生命周期对象的实例。7.Android最常发生内存泄漏的是什么?Activity(主播开始乱答,不知道对不对)8.让你设计一个检测Activity内存泄漏的算法,你会如何设计?主播真的不会啊,但主播还是要说...在onDestory中判断一下?然后问主播具体一点呢?主播答不知道9.说一下java里面的引用类型?主播说String、List这些?哈哈,面试官尴尬的笑了,说不是,比如说强引用、弱引用这些主播开始回答:强引用:只要对象被持有,就无法被回收软引用:只要内存不够,对象就会被回收弱引用:只能存活到下一次回收前,对象就会被回收虚引用:其实不会真正的持有对象的引用,一般用于追踪对象的生命周期。10. 能说一下java的垃圾回收机制吗?首先要判断对象是否要进行回收,常用的算法有引用计数法,就是对象被引用一次就进行计数,为0就说明没有引用,可以回收;第二个就是根部搜索法,从根部开始搜索对象引用链,没有被搜索到的就是没有引用,可以回收;再者就是要进行垃圾回收,首先判断对象的类型,是新生代还是老年代,采用不同的回收算法,因为新生代的对象的生命周期一般比较短,而老年代的生命周期比较长,一般新生代的一般采用复制算法,而老年代则采用...(主播当时忘记那个名字了,没答出来),复制算法,主要就是把内存分为两部分,然后每次只对一部分进行回收,然后把存活的对象移动到另一部分;老年代采用的那个算法,主要也是把内存分为两部分,但是不是1比1分的,好像是1:1:8?然后每次只对1:1进行回收,然后把存活的移动到另一部分内存?这里主播不太记得了,主播答的太着急了,好多之前了解过的都没说出来11.看你简历里写了自定义控件,可以说一下View的绘制流程吗?主要是先进行测量onMeasure(),onMeasure中主要测量各种view的宽高,方便后面onLayout()进行布局摆放 然后进行布局onLayout(), 最近进行绘制onDraw()。又问具体是怎么测量的呢?主播又不知道了,因为主播没看过源码但主播还是选择说一点答,调用view自带的哪些getHeight(),哪些获得它们的宽高,然后进行计算?12.我看你项目使用的是MVVM架构,能否说一下什么是MVVM架构?MVVM架构是Android常用的架构之一,使用它能让我们的代码更加的简洁,它是由三层组成的,View层、ViewModel层、Model层,View层就是界面层,主要用于显示界面;ViewModel层主要用于处理View层和Model层的交互,使二者解耦,Model层就主要用于业务逻辑的处理,比如说网络请求这些。比如说,我们可以在Model层编写网络请求的代码,而后在ViewMode层进行调用,之后把数据放到LiveData里面,而后View层就可以监听这个LiveData实现数据的更新。13.常用的架构还有哪些?MVP和MVC14.能说一下MVVM架构和其余架构比较的优劣势吗?这里主播太紧张了,只说了MVP架构的劣势,面试官也没说什么,可能是主播答的太乱了,听不懂哈哈我的第二个项目xxx里面使用的就是MVP项目,感觉较大的缺点就是定义的接口会很多,比如说现在有两个界面同时都需要用到这个接口里面的函数,但是其中一个界面只需要这个接口里面的一个功能,但是还是要实现,就实现了他不需要的接口函数,就不符合设计模式里面的接口隔离原则15.看你项目里面使用了Retrofit,Retrofit是什么?Retrofit的实现原理了解吗?答,Retrofit是基于okHttp的又一层封装,本质上还是一个网络请求框架,主要是通过注解的形式来简化请求过程。主播没怎么看懂Retrofit的源码,所以如实说了不怎么了解源码说比较了解okhttp16.那okHttp的责任链是怎么实现的呢?首先是okhttp里面定义了一些默认的拦截器,从第一个拦截器开始,通过执行一个函数,通过索引来控制拦截器的执行过程,每个拦截器执行完自己的责任之后,就将索引+1,然后回调到原来的类,继续执行下一个拦截器的任务。这里主播答得比较乱,面试官好像没怎么听懂私密马赛17.能说一下tcp的四次挥手吗?tcp的四次挥手主要是用于断开连接的,第一次是由客户端发出,告知服务器我要断开连接了,第二次是服务器收到请求,告知客户端我收到你的请求了,但是由于服务器还有一些别的任务没有完成,所以还有再等一下才能断开连接,再发出第三次请求给客户端告知它可以断开连接了,而后第四次客户端就彻底断开连接了。(这里主播答的也是乱乱的,好紧张...)追问:少了第四次会怎么样?主播有点忘了哈哈,又开始乱说答,导致服务器资源无法释放?18.你觉得项目中比较有挑战的是什么呢?收藏功能的实现19.输入网址之后发生的一些列事情主播不太会,答了一点点,提到了DNS服务器,从DNS服务器中找到要发生的服务器地址,然后进行发送20.DNS主要实现了什么?主播不会21.说一下Java中synchronized(这个问题应该在前面,主播忘了位置了哈哈)被修饰的代码块,同时只能有一个线程进入...巴拉巴拉主播忘记了22.了解过java的acs吗?主播没听过哈哈,后来查了一下好像是一种对称加密算法然后手撕的算法主播都没撕出来一紧张就没什么思路1.一个生产者和五个消费者的模拟主播没思路,面试官说主要是锁同步的问题主播还是没思路,面试官人太好了,一再退让,说可以写伪代码写到一半,面试官看不懂了哈哈,让主播讲思路私密马赛生产者的任务是不断生产产品存到容器中,直到容器满消费者的任务是不断从容器中取产品,直到容器空或者当前容器被其他消费者占用2.螺旋数组的升级版大致是,给定一个数组,要求将数组 逆时针 螺旋填充为一个m*n的二维数组不出意外,主播不会,主播说做过类似的,但是没思路卡了十分钟左右,主播准备放弃(因为不好意思浪费面试官的时间),对面试官说没思路,面试官说之前写过的题有思路吗?主播开始答非所问,其实也答不出来,因为主播忘记了解法,大概只记得之前那道是先要判断循环填充的圈数,但是这道题是m可以不等于n的,所以主播不知道循环的条件,没有一点思路。主播太菜了私密马赛emmmm好像手撕的环节是在问问题的中间?然后就是聊天1.问职业规划2.问最近学习的新技术3.问实习最长时间4.问base意向是哪里5.问目前有没有别的面试6.问有没有考研的打算反问其实主播也不知道问什么好,哈哈1.现在项目主要是用哪些框架比较多答,和主流的都差不多,但是会有一些自己新的东西,大概是这样,哈哈,主播听不懂2.现在项目使用的语言都换成kotlin了吗?还是依旧使用java答,都是使用kotlin总时长差不多是50分钟好了,本次分享到此结束
重生之我在海淀化身为鹅孝子:感觉8的时候,就是想让你迁移一下LeakCanary的实现原理
点赞 评论 收藏
分享
评论
1
16
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务