Android基础——初学者必知的AIDL在应用层上的Binder机制

本文详细介绍了Android中AIDL的使用方法及Binder机制的工作原理。通过实例演示了如何搭建服务端与客户端进行数据交互,并深入分析了Binder机制的具体实现。

初学者必知的AIDL在应用层上的Binder机制

 

首先得理解几个概念:

IPC:Inter-Process Communication,进程间的通信或跨进程通信。简单点理解,一个应用可以存在多个进程,但需要数据交换就必须用IPC;或者是二个应用之间的数据交换。

Binder:Binder是Android的一个类,它实现了IBinder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式。通过这个Binder对象,客户端就可以获取服务端提供的服务或数据,这里的服务包括普通服务和基于AIDL的服务。

AIDL:Android Interface Definition language,它是一种Android内部进程通信接口的描述语言。

 

 

一、AIDL的使用

 

 

服务端:

创建一个服务端工程,在工程中点击右键New->AIDL->AIDL File,默认直接点确定,这时会在工程中出现一个aidl文件:

我们打开这个aidl文件,我们创建一个我们需要测试的方法:

由于Android Studio是要手动编译才能生成对应AIDL的java文件,既然aidl文件是个接口,那就必须存在着实现这个接口的类,点击编译,系统自动生成一个java类,该java类的代码就是整个Binder机制的原理所在(会在下面第二步骤介绍原理):

 

既然是个服务端,那么我们就要开始写服务了,创建一个类,继承Service:

 
 

 

既然是个服务,就必须在manifests文件中配置:

 

 
 

到现在服务端写好了,开启模拟器启动这个程序,记得在代码中开启服务:

 

 

 
 

 

 

客户端:

 

在工程中点击右键New->Module,按默认确定,finish:


关键的一步来了,复制服务端的aidl整个文件夹(包括里面的包、aidl文件、完整无缺)粘贴到客户端对应放aidl的地方


不要忘了,客户端还要手动编译

好了我们来写客户端的代码(我们在MainActivity中放一个”AIDL“的按钮,先绑定服务,然后点击按钮调用):

 

 
 

 

测试结果(先开启服务端,开启服务后,接着开启客户端,绑定远程服务):

 

 
 
 
 


 

二、AIDL的Binder机制原理分析

 

分析原理:

 

 
 

 

我们来分析一下这个类

首先本身继承Iinterface,所以他也是个接口,接口中必须有方法,代码定位到结尾有2个方法。

 

 
 

这两个方法就是basicTypes和add,就是我们服务端的2个方法。

 

接着发现该接口中有1个内部类Stub,继承自本身(IMyAidlInterface)接口,代码定位到Stub类。

这个Stub有个构造方法、asInterface、asBinder、onTransact(先不介绍)。

接着发现该内部类Stub还有一个内部类,代码定位到Proxy(我们把它称为代理)类,也是继承自本身(IMyAidlInterface)接口,所以实现该接口的两个方法。

 

 
 

在这个类里面我们会发现有2个标识:用来区分两个方法,到底你远程请求哪个方法的唯一标识,代码定位到代理类的结尾

 

 

 
 

回过头来,还记得我们客户端做了什么吗?答案:绑定一个服务,在回调方法获取一个接口(iMyAidlInterface),它是直接静态使用IMyAidlInterface里面的静态类Stub的asInterface的方法:(雅思高分作文好了我们去跟踪到Stub类asInterface这个方法)

 

 

 
 

代码定位到Stub类asInterface方法

 

 

 
 

前面只是做一些判断、看一下最后一句话:我们将传过来的obj还是传给了它的代理类来处理,返回的是代理类的对象

 

 

 
 

所以在客户端的iMyAidlInterface=……,则是拿到它的代理类,好了,这个时候就看客户端调用代理类干嘛了

 

 

 
 

他调用了代理类的add方法,代码定位到代理类的add方法

 
 

你会发现,它把数据写进了_data里面,最后调用transact方法,传入_data数据,唯一标识Stub.TRANSACTION_add。

 

 

 
 

然后这个transact方法就是通过底层了,通过底层结束后,这些参数送到哪了?答案:底层会走到stub类中的onTransact方法,通过判断唯一标识,确定方法:

 
 

在这个地方将传过来的参数解包,readInt方法。然后调用this.add方法,this指的就是服务端,调用服务端的add的方法:

 

 

 
 

将得到的结果,写入reply

 

 

 
 

最后一句话,最后返回系统的ontransact方法,传入结果reply:

 

 

 
 

所以我们在上面获得的结果就是reply(答案:3):

 

 

 
 

最后总结下整个过程



三、AIDL编写时候的一些错误

 

错误一:

 

 
 

这个错误很有可能是你写的服务端,忘记返回myS了,返回的是个null

 

 

 
 

错误二:

 

 
 

这个错误很有可能是的服务端在manifests文件中少了exported="true"的属性 

转载于:https://www.cnblogs.com/zhanglixina/p/9597625.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值