Android 插件化开发——基础底层知识(代理模式)

今天周六,接着自我学习插件化,今天学习代理模式,温习一下上一篇博客
Android 插件化开发——基础底层知识(反射)
关于代理模式,是众多设计模式中的一种,我想说在学习该知识点之前,也是云里雾里,只知道有这个东西,但是具体写代码就GG了,其实Android系统源码里就很多代理模式。


为什么需要代理模式?


  • 代理类在客户端和目标端起到中介作用,这样可以保护目标端,同时也能够给客户端提供相应的服务
  • 在开发情况下,目标端如果没有完成,客户端可以再是从代理类中获取相应的数据,而不会阻塞。

打个比喻:我们提供了个SDK,很多人都需要这个SDK服务,但是各自又有不同,此时就可以写一个代理类,此时各自扩展功能可以写在代理类中,而不用修改代理类。保护了SDK。

代理模式分为两种:静态代理和动态代理


静态代理


要理解静态代理,可以举个例子。
场景:在日常开发中,比如A同学和B同学各自开发一个模块,A同学要调用B同学的模块中的doSomeThing()方法,但是B同学还没有提供该方法的具体逻辑,那么怎么办呢?如果不提供doSomeThing, 那么A同学的工作就可能阻塞了,此时静态代理上场了。

可以写一个代理类,在代理类Proxy中写一个doSomeThing方法,然后返回假数据,等到B同学开发完了该模块之后,然后再在Proxy类中填写相应的代码,此时就OK了。

    public class ProxyClass {
        String doSomeThing() {
            .......
        }
    } 

这种是最简单的几个静态代理模式。

但是试想一下,如果我们代理类中有很多相应的方法,那么此时有一个需求,就是在所有方法中执行前,打印一句话,那么我们是不是得在每个方法中修改添加代码呢? 方法少了还好,如果成千上百呢? 是不是GG了? 此时动态代理上场了。


动态代理


关于动态代理需要用到一个东西:

Proxy.newProxyInstance(ClassLoader classLoader, Class[] interface, InvocationHandler h);

classLoader: 设置为目标对应的ClassLoader。
interface:设置为牧鞭所实现的接口类型。
InvocationHandler : 实现了InvocationHandler接口的类对象,通过其构造函数,将目标端对象传入。

举个栗子:
现在有一个超市,老板要卖商品,但是呢,老板肯定不会自己卖啊,一般都是雇员工卖商品,此时老板就是目标端,员工就是代理类,然后我们定义一个接口:包含所有超市的工作方法。

我们定义一个接口:

/**
 * author: liumengqiang
 * Date : 2019/6/21
 * Description :
 */
public interface ISupermarketInterface {
    void sellingGoods(); //卖商品
}

老板要卖商品:

/**
 * author: liumengqiang
 * Date : 2019/6/21
 * Description :老板卖商品
 */
public class Boss implements ISupermarketInterface {
    @Override
    public void sellingGoods() {
        System.out.print("老板卖出了商品");
    }
}

此时需要我们的员工卖东西:


/**
 * author: liumengqiang
 * Date : 2019/6/21
 * Description : 员工代卖
 */
public class Staff implements InvocationHandler {

    private ISupermarketInterface iSupermarketInterface ;
	//通过构造函数,传入老板的实例对象
    public Staff(ISupermarketInterface iSupermarketInterface) {
        this.iSupermarketInterface = iSupermarketInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName());
        //通过反射调用老板实例对象中的相应方法
        return method.invoke(iSupermarketInterface, args);
    }
}

他们之间怎么产生关系呢:

		//创建员工代理对象,返回传入的接口对象
       ISupermarketInterface iSupermarketInterface = (ISupermarketInterface) Proxy.newProxyInstance(ISupermarketInterface.class.getClassLoader(),
                new Class[]{ISupermarketInterface.class},
                new Staff(new Boss()));
		
		//调用接口对象的方法,都会进入到员工对象的invoke方法中,然后通过反射调用老板的相应方法。
        iSupermarketInterface.sellingGoods();

原理问题,在此不多讲,感兴趣的同学可以自行搜索。

Proxy.newProxyInstance方法是可以“套”在任何一个接口类型的对象上的,为这个对象增加新的功能。在插件化领域,我们可以通过Proxy.newProxyInstance生成的对象,替换掉原来的对象,这个就是Hook技术!

至此我们的基本技术学完了,总体看下我们的基础学习路线:

  1. Android 插件化开发——基础底层知识(Binder,AIDL)
  2. Android 插件化开发——基础底层知识(Context家族史,Activity启动流程)
  3. Android 插件化开发——基础底层知识(Service)
  4. Android 插件化开发——基础底层知识(反射)

加上本篇博客,基础知识大致学完了,接下来开始我们Hook技术探索!

你可能感兴趣的:(android开发,Android插件化开发,Android插件化开发)