小言_互联网的博客

Android IPC —— AIDL的原理

197人阅读  评论(0)

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的使用

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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场