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

前言

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

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

methodproxy的调用的任何方法

argsmethod的参数

接下来我们实现动态代理

(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下载地址:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值