Android中AIDL的跨进程通讯分析

在很早的时候,就已经接触过AIDL了,也在项目中用到,今天记录下AIDL的使用过程及其跨进程通讯的内部流程

一、如何实现AIDL跨进程

 需求是:实现添加和获取Student类

1、写Student类,必须进行实例化处理 Parcelable


   2、在项目工程app目录main下创建一个aidl文件夹

  

   

点击build——》make build会自动生成相应的java代码,生成的java代码目录:app-->build-->generated-->source--aidl-->debug/release

3、服务端代码实现

  

    建一个类StudentManageStub继承StudentManager.Stub,实现里面的接口方法

  

建一个服务,onBind方法,返回studentManageStub对象

再在清单文件中注册服务

服务端基本写完

4、客户端实现如下

      绑定服务端的服务

绑定服务的时候需要传入ServiceConnection对象,绑定成功后,ServiceConnection回调IBinder, 可以通过这个 asInterface(IBinder binder) 拿到 对象StudengManager对象

通过两个按钮,一个是获取Student列表,一个是添加Student对象

这就基本完成AIDL跨进程 服务和客户端的实现

二、AIDL跨进程原理分析

我们还是通过服务端和客户端进行分析
如下是客户端实现,

 

进入StudentManager.Stub.asInterface

首先从本地进程获取IInterface,如果获取到就返回该该com.yang.test.StudentManager,如果没有就返回

new com.yang.test.StudentManager.Stub.Proxy(obj)

获取到Stub或者Stub.Proxy实例的时候调用具体方法如下,

客户端是如何通过Proxy类将数据传给服务端,又如何通过Proxy获取服务端返回的数据的呢?

我们通过客户端调用aidl接口方法如下代码分析:

 

有一个Parcel这个类,他是存放或者读取数据的容器,会生成两个容器:_data和_reply,

通过如上代码可以知道,会将方法的传参数据存入_data中,那我们可以猜测_reply,肯定是返回值存入的容器

调用了Binder的transact方法,调用该方法后,客户端将会挂起当前线程,等候服务端执行完相关任务后通知并接收返回的 _reply 数据流,其中传入四个参数:

第一个参数Stub.TRANSACTION_getStudentList 为该方法生成的一个地址;

第二个参数是_data是入参;

第三个参数_reply应该是出参,看下 他的方法注解 ,注解解释很明白,是出参数据;

第四个参数它的作用是设置进行 IPC 的模式,为 0 表示数据可以双向流通,即 _reply 流可以正常的携带数据回来,如果为 1 的话那么数据将只能单向流通,从服务端回来的 _reply 流将不携带任何数据了,Android的AIDL这里都是设置0,为双向流通模式

 

如果涉及了定向 tag ,情况将会变得稍微复杂些,具体是怎么回事请参见这篇博文:AIDL定向TAG,in/out/inout

如下是服务端实现类,继承StudentManager.Stub,

进入StudentManager.Stub,可以看到Stub其实是.aidl文件生成.java文件里面的一个抽象静态内部类,其继承android.os.Binder,说明其实它就是一个Binder,通过Binder进行跨进程通讯

客户端调用transact,服务端通过这个方法onTransact,接收客户端传的参数,先判断code,将传过来的数据取出,调用本地的方法,最后将需要回传的数据写入reply流,回传给客户端

 

关于客户端一般的工作流程:

  • 1,生成 _data 和 _reply 数据流,并向 _data 中存入客户端的数据。
  • 2,通过 transact() 方法将它们传递给服务端,并请求服务端调用指定方法。
  • 3,接收 _reply 数据流,并从中取出服务端传回来的数据。

关于服务端的一般工作流程:

  • 1,获取客户端传过来的数据,根据方法 ID 执行相应操作。
  • 2,将传过来的数据取出来,调用本地写好的对应方法。
  • 3,将需要回传的数据写入 reply 流,传回客户端。

 

总结:在跨进程通信的时候,客户端绑定服务的成功,回调方法会返回Ibinder,通过Ibinder获取AIDL的Stub对象,在获取Stub对象的时候,会判断该Stub对象是否在该进程中存在, 如果存在返回该Stub对象,如果没有就获取该Stub的远程代理Proxy对象,然后,Client端使用Proxy里面封装了一个Binder与Server端的Stub(Stub继承Binder)进行交互,两个binder作为接口调用Binder 驱动的transact来发送数据包,以及onTransact接收处理数据包

 

这两篇博文写的也挺好的

Android进程间通信-AIDL实现原理

写给 Android 应用工程师的 Binder 原理剖析

 

 

 

 

 

 

 

      

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值