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

图 1-1

关于Proxy与Stub注意:

  1. Stub 跟 Proxy 是一对,俗称“代理-桩”,一般用在远程方法调用。
  2. Proxy 相当于是拿在手里的遥控器,而 Stub 相当于长在电视机里的遥控接收器,它们有着一一对应的接口方法,但操作的方向刚好相反。
  3. Proxy 的接口供客户端程序调用,然后它内部会把信息包装好,以某种方式(比如 RMI)传递给 Stub,而后者通过对应的接口作用于服务端系统,从而完成了“远程调用”。
  4. 一般不同进程间通信的时候都会用到这种模式。
  5. 关于Stub的asInterface(Binder), 可以返回Stub或Stub.Proxy(如果客户端和服务端在同一个进程下,那么asInterface()将返回Stub对象本身,否则返回Stub.Proxy对象)。我们都知道,Binder的工作机制客户端,Binder,服务端组成的,客户端和服务端都是通过Binder来交流的(Binder也是Android中一个java类)。AIDL生成的java代码中,Stub类是继承于Binder类的,也就是说Stub实例就是Binder实例。
  6. 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实现原理的更多相关文章

  1. Android 进程间通信——AIDL

    代码地址如下:http://www.demodashi.com/demo/12321.html 原文地址:http://blog.csdn.net/vnanyesheshou/article/deta ...

  2. Android开发之IPC进程间通信-AIDL介绍及实例解析

    一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用 ...

  3. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...

  4. Android 进程间通信

    什么鬼!单例居然失效了,一个地方设置值,另个地方居然取不到,这怎么可能?没道理啊!排查半天,发现这两就不在一个进程里,才恍然大悟-- 什么是进程 按照操作系统中的描述:进程一般指一个执行单元,在 PC ...

  5. (转)Android 系统 root 破解原理分析

    现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的 原理吗?root破解的本质是什么呢?难道是利用了Lin ...

  6. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- AIDL

    服务端: 最终项目结构: 这个项目中,我们将用到自定义类CustomData作为服务端与客户端传递的数据. Step 1:创建CustomData类 package com.ldb.android.e ...

  7. Android 使用AIDL调用外部服务

    好处:多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作, 本文包括: 1 .创建AIDL 服务端.2 .创建AIDL 客户端. 3.客户端调用服务端提供的 ...

  8. Android系统Recovery工作原理

    Android系统Recovery工作原理之使用update.zip升级过程分析(一)---update.zip包的制作 http://blog.csdn.net/mu0206mu/article/d ...

  9. Android启动篇 — init原理(二)

    ========================================================          ================================== ...

随机推荐

  1. 项目流程管理&&架构总结

    1 项目背景 所在业务在早期没有营销费用,买家购买商品的折扣优惠是由卖家提供的.全部订单的终于价格是由卖家和业务方确定的,整个购买流程非常easy. 如今此业务收受到公司重视,业务团队能申请到营销费用 ...

  2. BZOJ 1003 ZJOI2006 物流运输trans 动态规划+SPFA

    标题效果:给定一个无向图.输送n日,有一天的某一时刻不能去,更换行考虑k,求总成本 一阶cost[i][j]用于第一i为了天j天正在同一航线的最低消费 这种利用SPFA处理 然后就是移动的法规问题 订 ...

  3. 【Cocos2d-x Lua】数据库封装类型的操作

    Lua数据库封装类型的操作 使用演示样例 lua代码: require("DB") -- 保存一个字符串(数据库中存储的数据都是以字符串的形式保存的) DB:getInstance ...

  4. 寄存器,cache、伙伴系统、内存碎片、段式页式存储管理

    cache.伙伴系统.内存碎片.段式页式存储管理 目录 分层的存储管理 cache 局部性原理 置换算法 写回策略 linux环境下的cache 连续内存分配与内存碎片 内部碎片与外部碎片 动态分区分 ...

  5. 【23.15%】【codeforces 703C】Chris and Road

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. Docker简单的使用命令

    Hello World 使用[docker run]命令在docker container中执行应用程序 <pre name="code" class="plain ...

  7. win7 UAC bypass(微软已经给予了三组组件绕过UAC启动的特权)

    fireworm同学的翻译: 原文在http://www.pretentiousname.com/misc/win7_uac_whitelist2.html我只翻译了其中关于原理的一小部分,有兴趣的可 ...

  8. Callable,Runnable异同

    1.Runnable和Callable的区别 (1) Callable规定的方法是 call(), Runnable规定的方法是 run(). (2) Callable的任务执行后可返回值,而 Run ...

  9. Win10忘记ubuntu子系统密码

    原文:Win10忘记ubuntu子系统密码 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wf19930209/article/details/80 ...

  10. 实用WordPress后台MySQL操作命令

    关键字: WordPress MySQL 后台 数据库 地址:http://www.cnblogs.com/txw1958/archive/2013/01/06/wordpress-sql.html ...