AIDL中的in,out,inout

Android两个进程间内存相互独立不能互相访问,跨进程传输非默认类型对象需要先序列化,而不能直接简单传递引用,序列化的目的是将对象数据以能够在内存中流通的形式从一个进程传递到另一个进程,两个进程对象的传递类似深度clone,client端将对象数据写入Parcel(writeToParcel),server端从Parcel(readFromParcel)读取对象数据并重新创建一个同样的对象将读取到的数据填充到此对象,但这两个对象并不是一样的,只是他们的数据完全一样。
 

AIDL作为一种跨进程通信的方案,底层依赖Binder,跨进程通信时会调用AIDL中定义的方法,会把 caller(调用者,后文只用caller)的参数数据 copy 到 callee(接收者,后文只用callee),然后在callee进程中调用另外一个代理对象的相同方法,这个逻辑由Binder框架封装;使用者上层看起来,感觉是直接调用了对方进程中对象的方法。

AIDL文件在编译后会生成2个重要的实现类:

  • Stub
    callee被调用时,会通过Stub.onTransact(code, data, reply, flag)间接地调用本地对象(Local Binder)的对应方法。

  • Proxy
    caller调用AIDL方法时,最终通过Proxy调用remote.transact(code, _data, _reply, flag),然后通过Binder机制调用到远程的相应方法。

    上面的onTransact() 和 transact() 方法都是Binder定义的方法,更底层的跨进程逻辑由Binder机制实现,就不是本文的重点了。

根据源码和 demo 的验证结果,我们可以得出结论了:

Directional TagDesc
in数据从 caller传到 callee,callee 调用结束后不会把数据写回 caller 中。
outcaller 数据不会传入 callee(因为就没有写数据), callee 调用结束后(不管数据有没有更新)会把数据写回 caller 中。
inout数据从 caller 传到 callee,callee 调用结束后(不管数据有没有更新)会把数据写回 caller 中。

提了这么多次 caller 和 callee ,是不想把它们与 client 和 server 混淆;因为 client 与 server 可以互相调用,AIDL文件编译后的代码是一样的,client 与 server 在作为 caller 或 callee 时执行的(AIDL层)逻辑是相同的,所以不能说in / out / inout 是明确地表示 client 到 server 的方向(或者相反)。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaowang_lj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值