1、android中进程间通信有几种方法?
答:共享内存,管道,Socket,文件操作,Binder(Messenger, Bundle, AIDL)
2、在AIDL中的oneway关键字是起到什么作用?
答:oneway主要用在远程调用,本地调用都是同步调用,不受oneway影响。oneway关键字加在方法前表示该方法是异步方法,客户端在调用这个方法以后会立即返回,不会等待服务端的响应。如果没有添加oneway关键字,默认是同步方法,客户端会等待服务端处理完该方法后再继续执行。
3、oneway的使用场景有哪些?
答:1、不需要服务器响应的场景,例如客户端发送播放音乐的请求给服务端,服务端在播放音乐的过程中不需要向客户端发送任何响应。
2、性能要求高的场景,比如游戏和音视频通话等,可以减少客户端等待时间,提高系统响应速度和用户体验。
3、在处理大量并发请求时,可以减少客户端的阻塞 ,提升客户端用户体验。
4、异步通信,需要异步执行任务的时候。
4、oneway方法有什么隐患?
答:客户端调用同一个binder服务的不同方法(这里指的都是被oneway修饰的方法),这些调用都会被放入到binder node的async_todo队列中,串行执行。在客户端频繁调用,服务端又是耗时处理的时候,可能会有问题,比如binder频繁调用导致binder服务端处理不过来,binder驱动缓存没有及时释放导致后面的调用分配空间失败。Binder空间(1MB-8kb)。
5、AIDL中的客户端和服务端会在同一个线程中执行吗?
答:如果AIDL调用来自本地进程,即客户端和服务端都在一个进程中,则服务端的执行过程和客户端发起调用的方法在同一个线程。如果AIDL调用来自远程调用,即客户端和服务端在不同的进程,则服务端的执行过程在一个独立的线程中,并且对于客户端的每次调用,服务端的执行可能在不同的线程中执行,需要考虑并发的问题。
6、in、out、inout关键字是什么意思?
答:这三个关键字表示数据的流向,in表示客户端的数据可以流向服务端,out表示服务端的数据可以流向客户端,inout表示客户端和服务端的数据流向是可以双向的。基本数据类型默认为in,不能是别的;非基本数据类型需要指定一个关键字,因为这个关键字会影响数据的打包规则,从而影响性能。
7、如何使用AIDL?
答:1、创建.aidl文件,比如IRemoteService.aidl,在interface IRemoteService中定义相应的业务方法。如果引用了非基础类型,或者有callback回调,需要import对应的aidl文件路径,即使在同一个文件夹下,也需要import。如果有非基础数据类型,该类型需要实现Parcelable,并且在相应的aidl文件中写上 parcelable 类名。
2、编译下代码,Android Studio会自动生成相应的java文件,比如IRemoteService.java文件。在IRemoteService中定义了一个非常重要的抽象类Stub,其本质上是一个IBinder,我们在aidl文件中声明的接口出现在Stub中。
3、在服务端实例化Stub,在自定义的service中的onBind函数返回实例化的Stub类对象。
4、客户端使用bindService通过显式Intent绑定service,这里有一个ServiceConnection对象,当绑定成功以后,在方法onServiceConnected的参数中的IBinder就是和服务端通信的桥梁。使用IRemoteService.Stub.asInterface将IBinder转换为IRemoteService,这样就可以调用aidl中声明的接口方法了。
8、Android的进程间通信为啥选择Binder?
答:1、安全性,使用uuid标识进程身份;
2、性能和效率,使用内存映射,只需要一次数据拷贝;
3、稳定性,使用C/S架构,清晰明了,client与Service相对独立,稳定性较好。
9、Binder通信一次拷贝的原理是什么?
答:系统调用函数mmap(内存映射)不仅可以将文件映射到进程的用户空间(可以减少数据的拷贝次数,用内存读写取代I/O读写,提高文件读写效率),还可以将内核空间的一块区域映射到进程的用户空间。Binder跨进程通信就是借助了内存映射的方法,在内核空间和接收端用户空间的数据缓存区之间做了一层内存映射。这样从发送方用户空间拷贝到内核空间缓存区的数据,就相当于直接拷贝到了接收方的用户空间数据缓存区,从而减少一次数据拷贝。
1、Binder服务端(Service)在启动之后,通过系统调用Binder驱动(binder_open方法)在内核空间创建一个数据接收缓存区。
2、然后调用binder_mmap函数,先申请一块物理内存,然后建立binder服务端的用户空间与内核空间数据接收缓存区的映射关系。
3、客户端发送请求时,请求的数据在binder驱动中通过copy_from_user()将数据从用户空间拷贝到内核空间的缓存区中。由于内核缓存区和服务端进程的用户空间存在内存映射,这样就完成了一次进程间通信。
10、Binder通信,传递的数据大小上限是多少?为什么是这个数?
答:Binder通信数据大小取决于映射空间的大小(mapsize),是1M-8K 。
BINDER_VM_SIZE = 1 * 1024 * 1024 - PAGE_SIZE * 2。 PAGE_SIZE为页的大小,4K。
但是ServiceManager进程的内存映射空间大小是128K。