1.Bindler,AIDL,Messenger的关系
直观的看,Binder是Android中的一个类,实现了IBinder接口,从应用层角度,Binder是客户端与服务端通信的媒介。而IBinder接口定义了与远程对象的交互协议。
1.1 Bindler 与 AIDL
AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。其实AIDL文件的本质就是系统为我们提供的一种简单实现Binder的工具。仅此而已。如果我们可以自己去写生成的java文件,也就不用使用AIDL工具了。
1.2 Messenger与AIDL
Messenger的底层实现是AIDL,它对AIDL做了封装,使得我们可以更简便的使用进程间通信。
2. AIDL的使用
3. AIDL的原理分析
系统会为我们生成一个接口,这个接口继承了IInterface接口。
它里面有一个Stub类,这个Stub类继承自Binder类。通信的核心就是通过这个类来完成。
asInterface方法
这个方法在客户端在客户端调用的时候会用到,就是通过这个方法拿到对应的类,调用服务端暴漏给我们的方法。
可以看到如果服务端与客户端在一个进程,那么客户端调用的方法就是服务端的stub对应的方法。此时AIDL的作用就相当于一个服务端与客户端通信的普通接口,服务端用于实现接口方法,客户端直接调用即可。
如果不在一个进程,那么两个进程直接无法直接访问,共享资源。此时就通过调用Stub里面的Proxy方法,返回一个代理对象。
asBinder()方法
asBinder用于返回当前Binder对象。
可以看到,在刚才asInterface方法里面如果是跨进程通信的,在BindServicer时,ServiceConnection里面服务端传过来的IBinder对象最终会传到这里,赋值给mRemote。
onTransact()方法
onTransact方法运行在服务端的Binder线程池中。
客户端发起跨进程请求时,远程请求会通过系统底层封装后交给此方法来处理。
如果此方法返回false,那么客户端的请求就会失败。
- code : 确定客户端请求的目标方法是什么。
- data : 如果目标方法有参数的话,就从data取出目标方法所需的参数。
- reply : 当目标方法执行完毕后,如果目标方法有返回值,就向reply中写入返回值。
这个onTransact方法就是服务端处理的核心。接收到客户端的请求,并且通过客户端携带的参数,执行完服务端的方法,返回结果。
代理类Proxy
主要看一下上面的getBooks()方法。
当在跨进程通信服务端远程调用的方法就是这里的方法,首先创建该方法所需要的输入型Parcel对象_data,输出型_reply,和返回值对象_result。然后把该方法的参数信息写入_data中,接着调用transact方法来发起RPC(远程过程调用)请求,同时当前线程挂起;然后服务端的onTransact方法会被调用,直到RPC过程返回后,当前线程继续执行,并从_reply中取出RPC过程的返回结果。最后返回_reply中的数据。
** 整个过程的总结:**
Stub充当服务端角色,持有Binder实体(本地对象)。
- 获取客户端传过来的数据,根据方法 ID 执行相应操作。
- 将传过来的数据取出来,调用本地写好的对应方法。
- 将需要回传的数据写入 reply 流,传回客户端。
Proxy代理类充当客户端角色,持有Binder引用(句柄)。
- 生成 _data 和 _reply 数据流,并向 _data 中存入客户端的数据。
- 通过 transact() 方法将它们传递给服务端,并请求服务端调用指定方法。
- 接收 _reply 数据流,并从中取出服务端传回来的数据。
转载:https://blog.csdn.net/haazzz/article/details/116753360