Binder相关面试总结(三):Binder机制是如何跨进程的,一线互联网大厂面试真题系统收录

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

  • 创建实体类.aidl和对应的实体类.java文件。

Book.aidl

package com.wu.test.aidl;

parcelable Book;

Book.java

public class Book implements Parcelable {

//实体字段、实现序列化方法

}

  • 定义接口

interface BookController {

List getBookList();

void addBookInOut(inout Book book);

}

创建或修改过AIDL文件后需要clean下工程,使系统及时生成我们需要的文件

  • 创建Service供客户端调用

public class AIDLService extends Service {

private final BookController.Stub stub = new BookController.Stub() {

@Override

public List getBookList() throws RemoteException {

return bookList;

}

@Override

public void addBookInOut(Book book) throws RemoteException {

if (book != null) {

book.setName(“服务器改了新书的名字 InOut”);

bookList.add(book);

} else {

Log.e(TAG, “接收到了一个空对象 InOut”);

}

}

};

@Override

public IBinder onBind(Intent intent) {

return stub; //返回binder对象Stub

}

}

客户端

  • 把服务端的AIDL文件以及Book类复制过来,将 aidl 文件夹整个复制到和Java文件夹同个层级下,不需要改动任何代码。创建和服务端Book类所在的相同包名来存放 Book类。

  • 绑定服务,获取服务端的binder接口对象。

private ServiceConnection serviceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

bookController = BookController.Stub.asInterface(service); //绑定服务后,拿到接口对象

connected = true;

}

@Override

public void onServiceDisconnected(ComponentName name) {

connected = false;

}

};

//绑定服务

private void bindService() {

Intent intent = new Intent();

intent.setPackage(“com.wu.test”);

intent.setAction(“com.wu.test.action”);

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

}

aidl文件只是用来定义C/S交互的接口,Android在编译时会自动生成相应的Java类,生成的类中包含了Stub和Proxy静态内部类,用来封装数据转换的过程,实际使用时只关心具体的Java接口类即可。为什么Stub和Proxy是静态内部类呢?这其实只是为了将三个类放在一个文件中,提高代码的聚合性。

AIDL的使用

为何选择Binder方式

在讨论这个问题之前,我们知道Android也是基于Linux内核,Linux现有的进程通信手段有以下几种:

  • 管道:在创建时分配一个page大小的内存,缓存区大小比较有限;

  • 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;

  • 共享内存:无须复制,共享缓冲区直接附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;

  • 套接字:作为更通用的接口,传输效率低,主要用于不同机器或跨网络的通信;

  • 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;

既然有现有的IPC方式,为什么重新设计一套Binder机制呢。主要是出于三个方面的考量:

  • 效率:传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。从Android进程架构角度分析:对于消息队列、Socket和管道来说,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到接收方的缓存区,一共两次拷贝。

对于Binder来说,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同一块物理地址的,节省了一次数据拷贝的过程,如图:

  • 稳定性:共享内存不需要拷贝,Binder的性能仅次于共享内存。共享内存的性能优于Binder,那为什么不采用共享内存呢,因为共享内存需要处理并发同步问题,容易出现死锁和资源竞争,稳定性较差。Socket虽然是基于C/S架构的,但是它主要是用于网络间的通信且传输效率较低。Binder基于C/S架构 ,Server端与Client端相对独立,稳定性较好。

  • 安全性:传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Binder机制为每个进程分配了UID/PID,且在Binder通信时会根据UID/PID进行有效性检测。

Binder机制的作用和原理

Linux系统将一个进程分为用户空间和内核空间。对于进程之间来说,用户空间的数据不可共享,内核空间的数据可共享,为了保证安全性和独立性,一个进程不能直接操作或者访问另一个进程,即Android的进程是相互独立、隔离的,这就需要跨进程之间的数据通信方式。普通的跨进程通信方式一般需要2次内存拷贝,如下图所示

在这里插入图片描述

一次完整的 Binder IPC 通信过程通常是这样:

  • 首先 Binder 驱动在内核空间创建一个数据接收缓存区。

  • 接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系。(Binder IPC 机制中涉及到的内存映射通过 mmap() 来实现,mmap() 是操作系统中一种内存映射的方法。内存映射简单的讲就是将用户空间的一块内存区域映射到内核空间。映射关系建立后,用户对这块内存区域的修改可以直接反应到内核空间;反之内核空间对这段区域的修改也能直接反应到用户空间。)

  • 发送方进程通过系统调用 copyfromuser() 将数据 copy 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。

在这里插入图片描述

数据接收缓冲区映射如何实现?

Binder驱动实现了mmap()系统调用,这对字符设备是比较特殊的,因为mmap()通常用在有物理存储介质的文件系统上,而象Binder这样没有物理介质,纯粹用来通信的字符设备没必要支持mmap()。Binder驱动当然不是为了在物理介质和用户空间做映射,而是用来创建数据接收的缓存空间。先看mmap()是如何使用的:

fd = open(“/dev/binder”, O_RDWR);

mmap(NULL, MAP_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);

这样Binder的接收方就有了一片大小为MAP_SIZE的接收缓存区。mmap()的返回值是内存映射在用户空间的地址,不过这段空间是由驱动管理,用户不必也不能直接访问(映射类型为PROT_READ,只读映射)。

mmap()分配的内存除了映射进了接收方进程里,还映射进了内核空间。所以调用copy_from_user()将数据拷贝进内核空间也相当于拷贝进了接收方的用户空间,这就是Binder只需一次拷贝的‘秘密’。

Binder框架中ServiceManager的作用

Binder框架 是基于 C/S 架构的。由一系列的组件组成,包括 Client、Server、ServiceManager、Binder驱动,其中 Client、Server、Service Manager 运行在用户空间,Binder 驱动运行在内核空间。如下图所示:

在这里插入图片描述

  • Server&Client:服务器&客户端。在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。

  • ServiceManager(如同DNS域名服务器)服务的管理者,将Binder名字转换为Client中对该Binder的引用,使得Client可以通过Binder名字获得Server中Binder实体的引用。

  • Binder驱动(如同路由器):负责进程之间binder通信的建立,计数管理以及数据的传递交互等底层支持。

Service Manager是Binder进程间通信的核心之一,它扮演着Binder进程间通信机制上下文管理者的角色,同时负责管理系统的Service组件,并且向Client组件提供获取Service代理对象的服务。

Service Manager运行在一个独立进程中,因此和Client和Service通信也是运用Binder进程间通信机制来交互的。ServiceManager 和其他进程同样采用 Bidner 通信,ServiceManager 是 Server 端,有自己的 Binder 实体,其他进程都是 Client,需要通过这个 Binder 的引用来实现 Binder 的注册,查询和获取。ServiceManager 提供的 Binder 比较特殊,它没有名字也不需要注册。当一个进程使用 BINDERSETCONTEXT_MGR 命令将自己注册成 ServiceManager 时 Binder 驱动会自动为它创建 Binder 实体(这就是那只预先造好的那只鸡)。其次这个 Binder 实体的引用在所有 Client 中都固定为 0 而无需通过其它手段获得。也就是说,一个 Server 想要向 ServiceManager 注册自己的 Binder 就必须通过这个 0 号引用和 ServiceManager 的 Binder 通信。

Service Manager主要是负责如下:

  1. 打开和映射Binder设备文件;

  2. 注册为Binder上下文管理者;

  3. 循环等待Client进程请求;

  4. 管理ServiceManager代理对象;

  5. Service组件创建,同时需要在注册ServiceManager;

  6. 管理Service代理对象;

总结图

在这里插入图片描述

Binder进程间通信模型

在这里插入图片描述

总结

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

以上就是总结的关于在面试的一些总结,希望对大家能有些帮助,除了这些面试中需要注意的问题,当然最重要的就是刷题了,这里放上我之前整理的一份超全的面试专题PDF

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

这里只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

外链图片转存中…(img-nzjI57h8-1713053463340)]

这里只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-TAZYR9fP-1713053463340)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 24
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值