前言

我在[003]AIDL是什么中介绍的AIDL,但是好像还有朋友不明白问我,那我就来写一个终极版的文章,让你十分钟彻底明白AIDL,以下代码全为手写。

目标

Server进程注册一个Binder服务到SM,该Binder服务提供两个接口:add和minus
Client 进程通过SM获得Binder服务的代理类BinderProxy,并调用两个接口add,minus

1 没有AIDL的世界

1.1 Server进程

    class CommandBinder extends Binder {@Overrideprotected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {if (code == 1) {int a = data.readInt();int b = data.readInt();reply.writeInt(a + b);return true;} else if (code == 2) {int a = data.readInt();int b = data.readInt();reply.writeInt(a + b);return true;}return super.onTransact(code, data, reply, flags);}}void main() {//注册binder服务ServiceManager.addService("command", new CommandBinder());}

1.2 Client进程

    int add(int a, int b) {int code = 1;BinderProxy mClient = ServiceManager.getService("command");Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();mClient.transact(code, data, reply, 0);//flag设置成0,调用这个方法会跨进程调用Binder服务类中onTransact方法int result = reply.readInt();return result;}int minus(int a, int b) {int code = 2;BinderProxy mClient = ServiceManager.getService("command");Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();mClient.transact(code, data, reply, 0);//flag设置成0,调用这个方法会跨进程调用Binder服务类中onTransact方法int result = reply.readInt();return result;}

2 有AIDL的世界

AIDL文件

    //aidlinterface ICommand {int add(int a, int b);int minus(int a, int b);}

2.1 Server进程

与1.1中代码比较,我们发现,我们不是直接继承Binder,而是继承aidl文件自动生成ICommandBinder,我们只需专注写add和minus接口的实现,不需要在Binder类中的onTransact写一堆if else代码和Parcel.read write.

    class ADILCommandBinder extends ICommandBinder {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int minus(int a, int b) {return a - b;}}void main() {//注册binder服务ServiceManager.addService("command", new ADILCommandBinder());}

2.2 Client进程

与1.2中代码比较,我们发现,我们不需要写Parcel.read write和BinderProxy.transact,而是用BinderProxy对象构造一个CommandBinderProxy对象,然后直接调用CommandBinderProxy的add和minus

    int add(int a, int b) {BinderProxy mClient = ServiceManager.getService("command");return new CommandBinderProxy(mClient).add(a, b);}int minus(int a, int b) {BinderProxy mClient = ServiceManager.getService("command");return new CommandBinderProxy(mClient).minus(a, b);}

3 ADIL自动生成了什么代码

生成了三个部分:ICommand,ICommandBinder,CommandBinderProxy

3.1 ICommand

看起来和aidl文件差不多

    interface ICommand {int add(int a, int b);int minus(int a, int b);}

3.2 ICommandBinder

继承于Binder,并实现ICommand,然后在onTransact方法中调用还没有实现的add和minus方法

   abstract public class ICommandBinder extends Binder implements ICommand {int add = 1;int minus = 2;@Overrideprotected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {if (code == 1) {int a = data.readInt();int b = data.readInt();reply.writeInt(add(a, b));return true;} else if (code == 2) {int a = data.readInt();int b = data.readInt();reply.writeInt(minus(a, b));return true;}return super.onTransact(code, data, reply, flags);}abstract public int add(int a, int b);abstract public int minus(int a, int b);}

3.3 CommandBinderProxy

对BinderProxy进行封装,把调用CommandBinderProxy的add转化成Parcel.write,read和BinderProxy.transact代码。

    public class CommandBinderProxy implements ICommand {private BinderProxy remote;int add = 1;int minus = 2;public CommandBinderProxy(BinderProxy remote) {this.remote = remote;}@Overridepublic int add(int a, int b) {Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();remote.transact(add, data, reply, 0);int result = reply.readInt();return result;}@Overridepublic int minus(int a, int b) {int code = 2;Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();remote.transact(code, data, reply, 0);int result = reply.readInt();return result;}}

总结

看完应该明白了AIDL作用主要有
a.偷懒,少很多代码,尤其是你要写上百个方法的时候,AIDL就派上大用场了。
b.让服务端更专注接口的实现,而减少犯错误的可能性
c.规范client端和server端的接口定义,有助于代码的迭代

当然这是我自己写的伪代码,AIDL真正生成的代码比较复杂,但这些伪代码就是AIDL核心点。

思考

oneway的这个语法对AIDL生成的代码有什么影响,或者你们自己写一下oneway的方法AIDL生成的伪代码


回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

十分钟让你明白AIDL相关推荐

  1. 十分钟让你明白Objective-C的语法(和Java、C++的对比)

    2019独角兽企业重金招聘Python工程师标准>>> 很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头疼, ...

  2. 不会吧不会吧,不会真有人还不会算时间复杂度吧?用十分钟让你明白如何计算时间复杂度

    前言: 算法的分析方式有两种: 事后分析统计方法:编写算法对应程序,统计其执行时间. 存在问题:编写程序的语言不同,执行程序的环境不同等因素 事前估算分析方法:撇开上述因素,认为算法的执行时间是问题规 ...

  3. 十分钟让你明白蓄水池算法

    蓄水池算法 1.蓄水池原理 如图,一个游泳池,池内水是活水,也就是有水不断地进入,也有一端不断往外流出,理论上池中水会被全部替换,其实随着水流的流动,会存在一部分水还是之前的水,有一部分会被替换,这也 ...

  4. 想玩明白Hive哪有那么容易,十分钟你都看不完

    通读大概需要十分钟 HIVE 什么是数据仓库 什么是Hive Hive架构 Hive的优缺点 Hive和数据库比较 Hive基本数据类型 Hive集合数据类型 类型转化 DDL数据操作 创建数据库 查 ...

  5. 看后至少多活十年--只需十分钟

    看后至少多活十年--只需十分钟 看后至少多活十年--只需十分钟 -北大齐教授健康讲座笔录- 看后至少多活十年!!!~~~~不要死于无知~~~~不但要保养好自己,回家也要告诉父母这么做~~~~这是好东西 ...

  6. 十分钟,让你了解DSP/DMP/SSP

    十分钟,让你了解DSP/DMP/SSP 首先,你对互联网广告的产业链要至少有一个基本的了解. 广告主advertisers,显然是指想为自己的品牌或者产品做广告的人,例如宝马.Intel.蒙牛-- 媒 ...

  7. html网页和cgi程序编程,十分钟搞懂什么是CGI

    原文:CGI Made Really Easy,在翻译的过程中,我增加了一些我在学习过程中找到的更合适的资料,和自己的一些理解.不能算是严格的翻译文章,应该算是我的看这篇文章的过程的随笔吧. CGI真 ...

  8. 十分钟掌握 “UML ” 的基本使用

    十分钟掌握 "UML " 的基本使用 每博一文案 很喜欢这样一段话:内可以不跟别人计较,但一定要学会维护自己,你可以不跟别人争抢,但应该懂得远离小人. 人生在世,我们会遇到形形色色 ...

  9. 一分钟让你明白OKR考核

    一分钟让你明白OKR考核 HR·易 HR·易,是由一群热爱人力资源人士专心运营的HR社区,聚焦于HR的招聘.社交.资讯.工具与成长.HR,so easy! 一.什么是OKR体系? OKR体系的全称是O ...

最新文章

  1. 左神讲算法——异或的高级操作(两数交换+经典面试题)
  2. JS 事件冒泡和事件捕获
  3. Android UI法宝的设计资源的开发
  4. 能用条件注释改善的IE兼容问题
  5. 如何使用plantUML生成go项目的UML图?(mac)
  6. java freememory 单位_Runtime类中的freeMemory,totalMemory,maxMemory区别
  7. androidannotations gradle Android Studio
  8. python写我爱你_12个精选Python教程我的初恋故事。
  9. python变量的数据类型
  10. win10无法装载重装系统iso文件_华硕笔记本怎么自己重装系统|华硕笔记本自己装系统教程...
  11. apue.h文件找不到的解决办法
  12. 【优化算法】杂草优化算法(IWO)【含Matlab源码 1076期】
  13. 并发编程常见面试题总结五
  14. Linux中chmod命令修改权限详解
  15. 用于计算成像的超材料
  16. 【GMSK+FPGA】基于verilog的GMSK调制系统设计
  17. python中shape 0_Python错误:找到包含0个样本(shape =(0,262))的数组,同时至少需要1个...
  18. 三阶魔方大中小魔公式_三阶魔方花样大汇总 ,带公式带图
  19. 淘宝API接口:获取sku详细信息
  20. 7z压缩软件dos命令

热门文章

  1. 中断共享(硬件角度)
  2. 利用Excel VBA畫出所有圖標
  3. 学成在线--0.项目概述
  4. JAVA如何取得空list成员类型_String 类型的List作为一个成员变量保存,保存成功后取对象时报空指针...
  5. lisp语言cond和if套用_LISP - 决策
  6. SecureCRT常用的使用技巧
  7. MFC CPropertySheet 多页面切换 实例
  8. 第一季5:Hi3518EV200的环境搭建
  9. LeetCode8——String to Integer (atoi)(自己编写atoi函数)
  10. 《C++标准程序库》学习笔记5 — 第七章