Android设计模式源码解析之Proxy模式

Android设计模式源码解析之Proxy模式

本文为 Android 设计模式源码解析 中 Proxy模式 分析 Android系统版本: 5.0 分析者:singwhatiwanna,分析状态:完成,校对者:Mr.Simple,校对状态:已校对

Binder中的代理模式

再说Binder中的代理模式之前,我们需要先看看代理模式的简单实现,这一部分内容采用了《JAVA与模式》之代理模式这篇文章中的代码示例和uml类图。

1. 模式介绍

代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

模式的使用场景

就是一个人或者机构代表另一个人或者机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

2. UML类图

角色介绍3. 模式的简单实现简单实现的介绍

下面通过一种抽象的方式来实现下代理模式

实现源码

抽象对象角色

AbstractObject {();}

目标对象角色

{() {//一些操作System.out.println(“一些操作”);}}

代理对象角色

{RealObject realObject = new RealObject();() {//调用目标对象之前可以做相关操作System.out.println(“before”);realObject.operation();//调用目标对象之后可以做相关操作System.out.println(“after”);}}

客户端

public class Client {(String[] args) {AbstractObject obj = new ProxyObject();obj.operation();}}4. 代理模式在Binder中的使用

直观来说,Binder是Android中的一个类,,它继承了IBinder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在linux中没有;从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager,etc)和相应ManagerService的桥梁;从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当你bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。

Binder一个很重要的作用是:将客户端的请求参数通过Parcel包装后传到远程服务端,远程服务端解析数据并执行对应的操作,同时客户端线程挂起,当服务端方法执行完毕后,再将返回结果写入到另外一个Parcel中并将其通过Binder传回到客户端,客户端接收到返回数据的Parcel后,Binder会解析数据包中的内容并将原始结果返回给客户端,至此,整个Binder的工作过程就完成了。由此可见,Binder更像一个数据通道,Parcel对象就在这个通道中跨进程传输,至于双方如何通信,这并不负责,只需要双方按照约定好的规范去打包和解包数据即可。

为了更好地说明Binder,这里我们先手动实现了一个Binder。为了使得逻辑更清晰,这里简化一下,我们来模拟一个银行系统,这个银行提供的功能只有一个:即查询余额,只有传递一个int的id过来,银行就会将你的余额设置为id*10,满足下大家的发财梦。

先定义一个Binder接口package com.ryg.design.manualbinder;import android.os.IBinder;import android.os.IInterface;import android.os.RemoteException;{static final String DESCRIPTOR = “com.ryg.design.manualbinder.IBank”;TRANSACTION_queryMoney = (IBinder.FIRST_CALL_TRANSACTION + 0);(int uid) throws RemoteException;}

2.创建一个Binder并实现这个上述接口

package com.ryg.design.manualbinder;import android.os.Binder;import android.os.IBinder;import android.os.Parcel;import android.os.RemoteException;{public BankImpl() {this.attachInterface(this, DESCRIPTOR);}public static IBank asInterface(IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof IBank))) {return ((IBank) iin);}return new BankImpl.Proxy(obj);}@Overridepublic IBinder asBinder() {return this;}(int code, Parcel data, Parcel reply, int flags)throws RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_queryMoney: {data.enforceInterface(DESCRIPTOR);int uid = data.readInt();long result = this.queryMoney(uid);reply.writeNoException();reply.writeLong(result);return true;}}return super.onTransact(code, data, reply, flags);}(int uid) throws RemoteException {return uid * 10l;}{private IBinder mRemote;Proxy(IBinder remote) {mRemote = remote;}@Overridepublic IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}(int uid) throws RemoteException {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();long result;try {data.writeInterfaceToken(DESCRIPTOR);data.writeInt(uid);mRemote.transact(TRANSACTION_queryMoney, data, reply, 0);reply.readException();result = reply.readLong();} finally {reply.recycle();data.recycle();}return result;}}}

ok,到此为止,我们的Binder就完成了,这里只要创建服务端和客户端,二者就能通过我们的Binder来通信了。这里就不做这个示例了,我们的目的是分析代理模式在Binder中的使用。

我们看上述Binder的实现中,有一个叫做“Proxy”的类,它的构造方法如下:

Proxy(IBinder remote) {mRemote = remote; }你被雨淋湿的心,是否依旧。

Android设计模式源码解析之Proxy模式

相关文章:

你感兴趣的文章:

标签云: