在小7写的上一篇文章《android IPC通信机制梳理》里,我讲到了如果activity要想和一个跨进程的Service进行通信就需要通过Binder框架,获取到IBinder对象,并调用transact()方法来达到通信的目的。该方法里的第一个参数是整数型的code,表示的是请求的服务类型,比如说我想请求使用某播放器服务,我就需要制定一个规则:当code为1时表示开始播放,当code为2时表示停止播放,当code为3时表示下一首歌曲。。。这中方法有几个问题:

  1. 这个规则需要Activity和Service这对交互的双方共同知晓,也就是说,Service必须很清楚code的每个值代表对方要求哪个操作,这种形式非常不直观,也容易出错。
  2. 这种方法在需要请求的操作数量较少的时候还可以忍受。可是如果数量非常多的时候,维护起来可就有点蛋疼了,而且在Service端实现自己的Binder对象方法里面不可避免需要写大量的if else块说着是switch case块,非常的不简洁又很难维护。

除了维护code不方便外,假如通信的时候需要一些额外的参数的话,Activity需要用一个Parcel对象把需要的参数依次写进去,再把该Parcel对象作为transact()方法的另一个参数传给Service。当Service这边的Binder对象得到该参数后,也必须按照之前写进去的次序依次读出来。看到了这么多不人性的交互方式,还能忍吗?所以找到一个更加人性化更加优雅的方法进行通信势在必行。

这个时候我们可以想一个办法,在Activity和IBinder对象之间找到这么一个中介,它要做的就是明白我们人类都懂的人性化接口比如:
<code>
interface IDoor{
public void open();
public void close();
public void alarm();
}
</code>
然后在它的内部把这些人性化的接口请求翻译成Binder明白的请求,也叫编码,这样Activity本身就不需要去了解什么IPC通信方式了,只需要调用这些基本的业务接口就好了。这个中介拿我们的术语来说就是Proxy了。所以我们可以这样来实现一个DoorProxy类:
<code>
public class DoorProxy implements IDoor{
private IBinder binder;
public DoorProxy(IBinder binder){
this.binder = binder;
}
public void open(){
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
binder.transact(1,data,reply,0);
}
}</code>
这个类DoorProxy就起到了这么一个中介的作用。同样的,在Service端和Binder对象之间也需要这么一个中介,把Activity那边传过来的IPC通信编码解码成我们人类抖动的人性化接口,比如:
<code>
public abstract class DoorStub extends Binder implements {
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
if(code == 1){
open();
}
}
public abstract void open();
public abstract void close();
public abstract void alarm();
}
</code>
这样的话Service端自己定义的Binder对象只需要继承这个DoorStub类就可以了。

 
aidl2.png

当有了Proxy以及Stub这两个中介,是不是我们一下子又可以轻松愉快的只关注业务了呢。现在问题来了,既然前面讲的这两个中介能缓解 我们好多的工作负担,谁又负责来实现它们呢?如果是我们自己实现的话,不是一样的吗?只不过把原来一个类里做的事情搬到了另一个类里而已吗?这个时候该是AIDL出场的时候了,大家还想的起来AIDL做什么的吗,它不就是让我们开发者自己定义一个业务接口,然后通过aidl的代码生成器,根据接口自动生成了我上面讲的两个中介的代码文件,我们需要做的仅仅是实现我们自己的stub类,把我们的业务代码放进去,另外在Activity里调用Proxy对象的方法而已。就是这么简单。至于AIDL具体的细节,我在这里就不多说了,相信通过上面的讲述已经很清楚了。也希望能对大家有点帮助。

 

从android aidl理解Proxy/stub模式的更多相关文章

  1. (转载)你真的理解Android AIDL中的in,out,inout么?

    前言 这其实是一个很小的知识点,大部分人在使用AIDL的过程中也基本没有因为这个出现过错误,正因为它小,所以在大部分的网上关于AIDL的文章中,它都被忽视了——或者并没有,但所占篇幅甚小,且基本上都是 ...

  2. Android中Adapter和Bridge模式理解和应用

    一 Adapter模式 意图: 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作. 适用性: 使用一个已存在的类,而它的接口 ...

  3. Android AIDL自动生成Java文件测试

    /******************************************************************************** * Android AIDL自动生成 ...

  4. Proxy 代理模式

    简介 代理模式是用一个简单的对象来代替一个复杂的或者创建耗时的对象. java.lang.reflect.Proxy RMI 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对 ...

  5. Proxy 代理模式 动态代理 cglib MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. AIDL/IPC Android AIDL/IPC 进程通信机制——超具体解说及使用方法案例剖析(播放器)

    首先引申下AIDL.什么是AIDL呢?IPC? ------ Designing a Remote Interface Using AIDL 通常情况下,我们在同一进程内会使用Binder.Broad ...

  7. java设计模式之Proxy(代理模式)

    java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...

  8. Android:活动的启动模式

    启动模式一共有四种,分别是 standard .singleTop . singleTask 和 singleInstance , 可 以 在 AndroidManifest.xml 中 通 过 给 ...

  9. 设计模式:代理(Proxy)模式

    设计模式:代理(Proxy)模式 一.前言    代理模式或许我们都听说过,至少知道代理(Proxy)这个东西的,否则看这篇博客也没任何意义的.什么叫做代理,代理是代替服务器去接受请求者的请求的中间人 ...

随机推荐

  1. struct的初始化

    1.struct的初始化可以使用类似数组的方式,如下:struct Student{ int _Age; string _Name;};Student stu = {26,"Andy&quo ...

  2. 壮士断腕!WordPress宣布停止使用React

    WordPress是一种使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站,也可以把WordPress当作一个内容管理系统(CMS)来使用. WordPr ...

  3. Android 高级 Jackson Marshalling(serialize)/Unmarshalling(deserialize)

    本文内容 高级 Jackson Marshalling 只序列化符合自定义标准的字段 把 Enums 序列化成 JSON 对象 JsonMappingException(没有找到类的序列化器) Jac ...

  4. DFS研究

    1.DFS和杀毒软件的影响:http://www.symantec.com/connect/forums/sep-and-dfs-replication 2.DFS深度:http://technet. ...

  5. Linux中使用sed命令或awk命令修改常规配置文件

    一.方案: Linux中使用sed命令或awk命令修改常规配置文件 二.步骤: 1.假设有一个a.txt,内容如下: #!/bin/bash aa= bbb= ccc= #ddd= 2.如果想要把里面 ...

  6. SqlServer2012自增主键跳跃增长的问题解决方案

    1.问题:SqlServer2012自增主键插入几条数据,然后重启服务,然后再插入几条数据,发现重启后插入的记录ID出现跳跃. 2.解决方案: Open SQLServer configuration ...

  7. VBA遍历数组的2种方式

      1.情景展示 VBA编程,如何对数组进行遍历? 2.解决方案 方式一:使用for循环 Sub 遍历数组1() '声明一个变量 Dim Arr As Variant '声明一个数字变量 Dim i ...

  8. java 多重循环

    //http://www.weixueyuan.net/view/6311.html //多重循环 import java.util.Scanner; public class Test16{ pub ...

  9. UAC 实现原理及绕过方法

    目录 0x00 UAC 工作流程 0x01 UAC 实现方法(用户登陆过程) 0x02 UAC 架构 0x03 触发UAC 0x04 UAC 虚拟化 0x05 UAC 逆向分析 1x00 UAC By ...

  10. Spring MVC测试框架详解——服务端测试

    随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的.从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用sp ...