Android进程间通信-AIDL实现原理
Android进程间通信基于Proxy(代理)与Stub(桩或存根)的设计模式(如图1-1所示)。其中,Proxy将特殊性接口转换成通用性接口,Stub将通用性接口转换成特殊性接口,二者之间的数据转换通过Parcel(打包)进行的,Proxy常作为数据发送代理,通过Parcel将数据打包发送,Stub常作为数据接收桩,解包并解析Parcel Data package。Android进程间通信就是通过这样的 “代理-桩” 的设计模式运作的。

图 1-1
关于Proxy与Stub注意:
- Stub 跟 Proxy 是一对,俗称“代理-桩”,一般用在远程方法调用。
- Proxy 相当于是拿在手里的遥控器,而 Stub 相当于长在电视机里的遥控接收器,它们有着一一对应的接口方法,但操作的方向刚好相反。
- Proxy 的接口供客户端程序调用,然后它内部会把信息包装好,以某种方式(比如 RMI)传递给 Stub,而后者通过对应的接口作用于服务端系统,从而完成了“远程调用”。
- 一般不同进程间通信的时候都会用到这种模式。
- 关于Stub的asInterface(Binder), 可以返回Stub或Stub.Proxy(如果客户端和服务端在同一个进程下,那么asInterface()将返回Stub对象本身,否则返回Stub.Proxy对象)。我们都知道,Binder的工作机制由客户端,Binder,服务端组成的,客户端和服务端都是通过Binder来交流的(Binder也是Android中一个java类)。AIDL生成的java代码中,Stub类是继承于Binder类的,也就是说Stub实例就是Binder实例。
- Stub和Stub.Proxy的区别:(1)如果在同一个进程下的话,那么asInterface()将返回服务端的Stub对象本身,因为此时根本不需要跨进称通信,那么直接调用Stub对象的接口就可以了,返回的实现就是服务端的Stub实现,也就是根本没有跨进程通信;(2)如果不是同一个进程,那么asInterface()返回是Stub.Proxy对象,该对象持有着远程的Binder引用,因为现在需要跨进程通信,所以如果调用Stub.Proxy的接口的话,那么它们都将是IPC调用,它会通过调用transact方法去与服务端通信。
关于AIDL定义以及实现流程图:
AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。我们在写完AIDL文件后,编译器会帮我们自动生成一个同名的 .java 文件(在gen相应目录下)。在服务端和客户端中也可以照常使用这个 .java 类来进行跨进程通信。

关于Proxy类几个对象及方法(客户端最终通过这个Proxy类与服务端进行通信):
- 关于 _data 与 _reply 对象:一般来说,我们会将方法的传参的数据存入_data 中,而将方法的返回值的数据存入 _reply 中—在没涉及定向 tag 的情况下。如果涉及了定向 tag ,情况将会变得稍微复杂些,具体是怎么回事请参见这篇博文:你真的理解AIDL中的in,out,inout么?
- 关于 Parcel :简单的来说,Parcel 是一个用来存放和读取数据的容器。我们可以用它来进行客户端和服务端之间的数据传输,当然,它能传输的只能是可序列化的数据。具体 Parcel 的使用方法和相关原理可以参见这篇文章:Android中Parcel的分析以及使用
- 关于 transact() 方法:这是客户端和服务端通信的核心方法。调用这个方法之后,客户端将会挂起当前线程,等候服务端执行完相关任务后通知并接收返回的 _reply 数据流。关于这个方法的传参,这里有两点需要说明的地方:
- 方法 ID :transact() 方法的第一个参数是一个方法 ID ,这个是客户端与服务端约定好的给方法的编码,彼此一一对应。在AIDL文件转化为 .java 文件的时候,系统将会自动给AIDL文件里面的每一个方法自动分配一个方法 ID。
- 第四个参数:transact() 方法的第四个参数是一个 int 值,它的作用是设置进行 IPC 的模式,为 0 表示数据可以双向流通,即 _reply 流可以正常的携带数据回来,如果为 1 的话那么数据将只能单向流通,从服务端回来的 _reply 流将不携带任何数据。
注:AIDL生成的 .java 文件的这个参数均为 0。
关于客户端一般的工作流程:
- 1,生成 _data 和 _reply 数据流,并向 _data 中存入客户端的数据。
- 2,通过 transact() 方法将它们传递给服务端,并请求服务端调用指定方法。
- 3,接收 _reply 数据流,并从中取出服务端传回来的数据。
关于服务端的一般工作流程:
- 1,获取客户端传过来的数据,根据方法 ID 执行相应操作。
- 2,将传过来的数据取出来,调用本地写好的对应方法。
- 3,将需要回传的数据写入 reply 流,传回客户端。
关于Android中AIDL的简单例子,参加如下Demo:
https://blog.csdn.net/jingwen3699/article/details/53400288
(注意:在Android Studio中,客户端和服务端的AIDL接口文件所在的包未必相同,最好在gradle中配置路径!)
其它参考链接:
https://blog.csdn.net/scnuxisan225/article/details/49970217
https://blog.csdn.net/a910626/article/details/51173668
https://blog.csdn.net/luoyanglizi/article/details/52029091 (详细原理来分析,good)
Android进程间通信-AIDL实现原理的更多相关文章
- Android 进程间通信——AIDL
代码地址如下:http://www.demodashi.com/demo/12321.html 原文地址:http://blog.csdn.net/vnanyesheshou/article/deta ...
- Android开发之IPC进程间通信-AIDL介绍及实例解析
一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用 ...
- 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...
- Android 进程间通信
什么鬼!单例居然失效了,一个地方设置值,另个地方居然取不到,这怎么可能?没道理啊!排查半天,发现这两就不在一个进程里,才恍然大悟-- 什么是进程 按照操作系统中的描述:进程一般指一个执行单元,在 PC ...
- (转)Android 系统 root 破解原理分析
现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的 原理吗?root破解的本质是什么呢?难道是利用了Lin ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- AIDL
服务端: 最终项目结构: 这个项目中,我们将用到自定义类CustomData作为服务端与客户端传递的数据. Step 1:创建CustomData类 package com.ldb.android.e ...
- Android 使用AIDL调用外部服务
好处:多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作, 本文包括: 1 .创建AIDL 服务端.2 .创建AIDL 客户端. 3.客户端调用服务端提供的 ...
- Android系统Recovery工作原理
Android系统Recovery工作原理之使用update.zip升级过程分析(一)---update.zip包的制作 http://blog.csdn.net/mu0206mu/article/d ...
- Android启动篇 — init原理(二)
======================================================== ================================== ...
随机推荐
- 在erlang项目中使用protobuf
在erlang项目中使用protobuf http://blog.csdn.net/mycwq/article/details/21864191 protobuf是google的一个序列化框架,类似X ...
- 小强的HTML5移动开发之路(15)——HTML5中的音频
浏览器虽然发展很快,但是浏览器中的标准还是不完善,在HTML4+CSS2+JS的前段开发中让很多程序员头疼的就是浏览器的兼容性问题,音频播放也一样,直到现在,仍然不存在一项网页上播放视频和音频的标准. ...
- linux 分发同步脚本与分发命令脚本
同步脚本,在第5步要拼接自己配置的主机名 #!/bin/bash # 获取输入参数个数,如果没有参数,直接退出 pcount=$# )); then echo no args; exit; fi # ...
- WCF客户端C#代码 配置config文件
不多说了,直接上代码吧.... 服务端Web.config文件中bindings配置 <bindings> <wsHttpBinding> <binding name=& ...
- jQuery Mobile移动开发
1.在<head>元素中包括JavaScript文件是传统的方法.然而,依据Yahoo!"80%的终于用户响应时间在前端上"的说法,这些事件大部分花在资产的下载上,比如 ...
- Troubleshooting routing topology based on a reference topology
In one embodiment, a computing device (e.g., border router or network management server) transmits a ...
- 我的MBTI职业性格测试
背景 最近在看<程序员的思维训练--开发人之前能的九堂课>,其中讲到了 MBTI 职业性格测试的指导意义.记起来两年多以前在面试 ASES 的时候有做过这个测试,只可惜当时的测试结果在好几 ...
- 打开一个很好的介绍Lucene4 FST文章
我没有看到源代码.看到这个博客了解一些基本的,像笔者下: http://download.csdn.net/download/guanxinquan/7380591 http://blog.sina. ...
- 如何用JS获取“ul”下边的“li”的个数
<script type="text/javascript"> function OnbtnClick() { var txtCount=document.getEle ...
- HTML:描述语义
一.HTML HTML:Hypertext Markup Launguage,超文本标记语言,是网页的就文件格式,用于描述网页语义. 二.HTML骨架 DTD手册:http://www.w3schoo ...