您的位置:首页 > 移动开发 > Android开发

android中利用代理模式简单实现界面之间的跳转与传值

2016-10-14 15:28 495 查看
前言

在开始这个实践之前,我们应该首先明白以下几个问题:

1.什么是代理模式?

2.为什么要使用它?

3.怎么使用它?

4.它的原理是什么?

什么是代理模式?

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

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

代理模式类图如下:



在代理模式中的概念:

  ●  抽象接口:代理类和委托类的共同接口,提供业务逻辑的声明。

  ●  代理类:代理类负责转发消息给委托类、并对委托类的访问进行控制

  ●  委托类:又被称为被代理类,负责具体业务逻辑的实现。

为什么要使用它?

使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。

怎么使用它?

根据程序运行时,代理类是否存在将代理分为静态代理和动态代理。

静态代理的使用如下:

抽象接口,负责具体业务声明

public interface IFactory {
void SellProduct();
}


委托类,负责具体业务的实现

public class FoodFactory implements IFactory{

@Override
public void SellProduct() {

System.out.print("sell food product");
}
}


代理类,负责控制委托类对象的访问

public class ProxyFactory implements IFactory {

private IFactory factory;

public ProxyFactory(IFactory factory) {
this.factory = factory;
}

@Override
public void SellProduct() {
//这里可以增加一些条件的判断,来控制对委托对象的访问
factory.SellProduct();
}
}


Junit单元测试

@Test
public void testStaticProxy() {
//静态代理测试
IFactory factory = new FoodFactory();
ProxyFactory proxyFactory = new                   ProxyFactory(factory);
proxyFactory.SellProduct();
}


分析:由上述代码可以看出,委托类FoodFactory只关注业务本身,代理类ProxyFactory的使用隐藏了业务具体实现,使得业务的重用性更高;然而在现实开发过程中,这种实现是非常少见的,一般情况,业务类会是多个接口的实现,而代理的过程中也需要实现这些接口,且根据不同业务封装,可能就会产生多个代理类而这时又因为功能需求,不得不访问这些接口的时候,这种代理方式就显得捉襟见肘了;这些情况下,就需要引用动态代理来解决了.

动态代理

在这里就利用动态代理来实现界面之间的跳转与传值,希望可以帮助大家更好的更透彻的理解动态代理的使用场景.

为了实现动态代理,要引入相关的类和接口 java.lang.reflect.Proxy 提供了一系列的static方法,用来创建代理类或对象,这个类是所有动态代理类的父类以及java.lang.reflect.InvocationHandler(调用处理器接口,只有一个invoke方法,处理动态代理类对象方法的调用,每个动态代理类都会关联一个InvocationHandler).

下面是对方法的介绍

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,InvocationHandler h)


-ClassLoader loader // 被代理类的类加载器,用来创建代理类

- Class<?>[] interfaces //被代理类实现的接口,创建的代理类会实现这些接口

- InvocationHandler invocationHandler //最关键的接口!它只有一个 invoke 方法,是代理类进行 拦截操作 的入口,一般需要自定义一个 Handler 来实现方法增强。

public Object invoke(Object proxy, Method method, Object[] args)


proxy 就是上面通过Proxy.newProxyInstance生成的对象proxy

method 是proxy的调用的任何方法

args 是method的参数


接下来我们实现动态代理

(1)编写抽象接口,声明activity之间的跳转

public interface Jumper {

@ActivityInfo(clz = NoParametersActivity.class)
IntentHandler gotoNoParametersActivity();

@ActivityInfo(clz = ParametersActivity.class)
IntentHandler gotoParametersActivity(@Extra(value = "param",author = "authorName")String userName);
}


(2)生成动态代理对象jumper





最重要的业务拦截处理在InvocationHandler中处理



(3)调用方法实现页面跳转并传参

jumper.gotoParametersActivity("15010").startActivity(this);


(4)在跳转页面获取值



只需要上面四步就可实现跳转,稍后我会奉上源码.

动态代理的实现原理

不说话, 直接附上源码,更好的理解动态代理机制









下面这段代码引入了(http://paddy-w.iteye.com/blog/841798)博客中的片段。
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });

m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);

m3 = Class.forName("***.RealSubject").getMethod("request",
new Class[0]);

m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);

} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
} //static

public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}

@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}

@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}

public final void request() {
try {
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}

@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}


这个类的生成最终是在Proxy中是在通过native方法Proxy.generateProxy生成类的字节码,再经过ClassLoader加载,就像class文件就被加载的过程,然后用newInstance方式生成最终的Proxy对象,具体的细节可以自行查看源码.

上面的$Proxy0就是生成的动态代理类,看到上面就明白代理类对方法的调用是怎么与InvocationHandler中invoke()方法关联的了,至此分析结束.

android中使用动态代理实现界面跳转传值demo下载地址:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android