Android中的代理模式

1. 什么是代理

 比如我们生活中的找出租屋,需要去找中介进行寻找挑选.而这里的中介就是代理.列子中看出代理特点如下1. 租客跟中介要做成的最终目的是一致的就是租到房子(目标一致).2. 中介资源多,有权利跟房东进行价格协商(功能强大).3. 中介是不会让我们直接跟房东进行协商(无法直接访问到目标). 我们在开发中也是有相似的情况出现你有个a类,本来是调用c类方法,完成某个功能.但是c类不让a直接调用.a-->不能直接调用c的方法在a和c之间直接创建一个b代理类,c让b访问.a-->访问b方法-->访问c方法


总结:我们在开发中使用代理模式是为了在不修改目标对象的基础上,增强主业务逻辑,客户类真正的想要访问的对象是目标对象,但是客户类真正可以访问的对象是代理对象.

2. 代理模式的作用

1.功能增强:在原有的功能上,增加额外的功能.
2.控制访问:代理类不让你访问到目标类.

3. 实现代理的方式-静态代理

1.自己手工实现的代理类.
2.代理的目标类是固定的.
特点:实现简单,容易理解.
举例子:
用户买鞋子行为
用户(客户端)-----商家(代理类)-----厂家(目标类)
其中,商家和厂家都是卖鞋子的,他们的完成的功能是一致的都是卖鞋子

    interface IShoesSell {//num 购买的数量 返回值是一双鞋子的价格public float sell(int num);}//特步厂家public class TebuShoesSellimpl implements IShoesSell {@Overridepublic float sell(int num) {return 300.0f;}}//京东商家public class JD implements IShoesSell {private IShoesSell mFactory = new TebuShoesSellimpl();@Overridepublic float sell(int num) {float price = mFactory.sell(num);price += 25;return price;}}public  void main(String[] args) {//创建代理对象-JD 进行购买JD jd =new JD();jd.sell(1); //这里我们就是通过京东购买了特步的鞋子325块}

我们可以在JD类sell方法进行功能增强(添加优惠券,满减等),也不难发现我们JD类里面的目标类是固定的(特步厂家TebuShoesSellimpl).

多添加厂家和商家代码的情况:

    //京东商家public class JD implements IShoesSell {private IShoesSell mFactory = new TebuShoesSellimpl();@Overridepublic float sell(int num) {float price = mFactory.sell(num);price += 25;return price;}}//拼多多商家public class PDD implements IShoesSell {private IShoesSell mFactory = new TebuShoesSellimpl();@Overridepublic float sell(int num) {float price = mFactory.sell(num);price -= 25;return price;}}//安踏厂家public class AntaShoesSellimpl implements IShoesSell {@Overridepublic float sell(int num) {return 350.0f;}}//京东商家-安踏public class JDAnta implements IShoesSell {private IShoesSell mFactory = new AntaShoesSellimpl();@Overridepublic float sell(int num) {float price = mFactory.sell(num);price += 25;return price;}}//拼多多商家-安踏public class PDDAnta implements IShoesSell {private IShoesSell mFactory = new AntaShoesSellimpl();@Overridepublic float sell(int num) {float price = mFactory.sell(num);price -= 25;return price;}}//这里就带来一个问题我只要添加一个目标类(安踏厂家),那我的代理类(商家)都要对应添加类,会出现一对n的变化,增加代码维护成本.


缺点:

  1. 目标类增多对应的代理类成倍增加.
  2. 当接口的方法进行添加修改时,会影响到众多类实现类需要修改,大大增加出错率.

4. 实现代理的方式-动态代理

优点:

  1. 代理类数量可以很少.
  2. 当你修改了接口中的方法时,不会影响代理类.

概念:
在程序执行过程中,使用jdk的反射机制,创建代理类对象,并动态的制定要代理目标类.
理解:
正常我们在java中想要创建对象是需要两个步骤

  1. 创建类文件,java文件编译成class文件.
  2. 使用构造方法new JD() ,创建类的对象.

动态代理直接是第二步骤(创建类的对象),跳过类文件创建.(so 文件少的原因)
动态代理的实现需要掌握的类(java.lang.reflect):

  1. InvocationHandler:
    接口,invoke方法里面填写功能代码
public Object invoke(Object proxy, Method method, Object[] args);
  1. Method:
    类中的方法,通过Method对象就可以执行某个方法. (invoke方法)
public native Object invoke(Object obj, Object ... args)
  1. Proxy:
    核心的对象,主要是创建代理对象.使用newProxyInstance()代替new.
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

实现动态代理完整代码

   IShoesSell mFactory = new TebuShoesSellimpl(); //特步厂家
// IShoesSell mFactory = new AntaShoesSellimpl(); //安踏厂家IShoesSell proxy = (IShoesSell)Proxy.newProxyInstance(mFactory.getClass().getClassLoader(), mFactory.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {float price = (float) method.invoke(mFactory, args);price += 30;// 京东代理//price -= 25; 拼多多代理return price;}});proxy.sell(1);

下面是实际的项目中的运用–获取项目中metaData数据进行修改
通过源码发现metadata 在ApplicationInfo中metaData属性.

private static void hookPM( ) {try {//获取ActivityThread对象Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");Field field = activityThreadClass.getDeclaredField("sCurrentActivityThread");field.setAccessible(true);Object activityThread = field.get(null);//获取了PackageManager对象Method getPackageManager = activityThread.getClass().getDeclaredMethod("getPackageManager");getPackageManager.setAccessible(true);Object iPackageManager = getPackageManager.invoke(activityThread);//获取IPackageManager接口的Class对象Class<?> iPackageManagerClass = Class.forName("android.content.pm.IPackageManager");//生成动态代理类Object pmProxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), //加载代理类的类加载器new Class[]{iPackageManagerClass}, //代理类需要实现的接口 (需要实现被代理类的接口)(proxy, method, args) -> { // 当被代理类的接口实现方法被调用时,会回调此实现类的invoke()方法,该方法中应该保证被代理类的原逻辑的执行(即 return时的调用)//ApplicationInfoif (method.getName().equals("getApplicationInfo")) {ApplicationInfo invoke = (ApplicationInfo) method.invoke(iPackageManager, args);if (invoke.metaData == null) {} else {Bundle metaData = invoke.metaData;metaData.putString("BD_KEY", "fdfdfdfffff");metaData.putString("GD_KEY", "fffffsdssss");}return invoke;} else {return method.invoke(iPackageManager, args);}});Field sPackageManagerField = activityThreadClass.getDeclaredField("sPackageManager");sPackageManagerField.setAccessible(true);sPackageManagerField.set(activityThread, pmProxy);} catch (Exception e) {e.printStackTrace();}}

5. 总结

Android中的代理模式相关推荐

  1. Android常见设计模式——代理模式(Proxy Pattern)

    文章目录 1. 前言 2. 代理模式(Proxy Pattern) 2.1 静态代理模式 2.2 动态代理模式 3. Android 中的代理模式 3.1 Retrofit中的代理模式(没有被代理者) ...

  2. Android常见设计模式——代理模式(Proxy Pattern)(二)

    文章目录 1. 前言 2. 远程代理(Remote Proxy) 3. 后记 1. 前言 在上篇Android常见设计模式--代理模式(Proxy Pattern)中基本上知道了什么是代理模式,以及对 ...

  3. 轻松学,Java 中的代理模式(proxy)及动态代理

    我们先来分析代理这个词. 代理 代理是英文 Proxy 翻译过来的.我们在生活中见到过的代理,大概最常见的就是朋友圈中卖面膜的同学了. 她们从厂家拿货,然后在朋友圈中宣传,然后卖给熟人. 按理说,顾客 ...

  4. Android中Activity启动模式

    Android中Activity启动模式一共是四种,这里我写一下我对其的理解: 1.standard(默认) 2.singleTop,如果某个Activity设置了该属性,且当前Activity就是这 ...

  5. 轻松学,Java 中的代理模式及动态代理

    前几天我写了<秒懂,Java 注解 (Annotation)你可以这样学>,因为注解其实算反射技术中的一部分,然后我想了一下,反射技术中还有个常见的概念就是动态代理,于是索性再写一篇关于动 ...

  6. 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...

  7. 第07课:生活中的代理模式——帮我拿一下快递

    用程序来模拟生活 从剧情中思考代理模式 代理模式的模型抽象 代码框架 类图 基于框架的实现 模型说明 代理模式的优点 代理模式的缺点 应用场景 [故事剧情] 八月中秋已过,冬天急速飞来--一场秋雨一场 ...

  8. android中的recovery模式

    这里使用基于freescale的imx_r9.2 patch的android源码分析. android中的recovery模式,作为android的开发者或者用户都应该清楚和了解.android利用r ...

  9. Spring中的代理模式

    Spring中的代理模式,是Spring中一大核心 AOP(切面编程)的底层实现. 代理模式可分为: 静态代理 动态代理 静态代理 涉及三类角色,简单分析一下: 抽象角色(一般会使用接口或抽象类解决) ...

最新文章

  1. 技术的那些事儿_3_西方技术管理的精髓
  2. SQL_Server2008数据连接池
  3. Redis是如何写代码注释的?
  4. 分布式机器学习_京东出来的java工程师,竟然不知道分布式、高并发、多线程的区别?...
  5. php加水印功能,PHP图片加水印功能
  6. Python之数据重塑——【stack()方法和unstack()方法、pivot()方法】
  7. 一个问题就可以辨别真假NLP(自然语言处理)研究者
  8. 正确评估SQL数据库性能,你必须知道的原理和方法!
  9. 在Jenkins远程链接Linux系统,然后执行shell命令-亲测可用【转】
  10. 红警 1 游戏开源,代码非常规范,网友:秀色可餐
  11. php-redis中文参考手册_zset
  12. csdn 博客添加目录方法
  13. stata中计算公式命令_Stata:runby - 一切皆可分组计算!
  14. apriori关联规则
  15. Linux内存管理宏观篇(五)物理内存:页面分配和释放页面
  16. 电商产品销售管理后台ui模板
  17. HYSPLIT简明教程
  18. Java 拾遗补阙 ----- 浅拷贝和深拷贝(对象克隆)
  19. 空气负氧离子监测系统建设方案
  20. 在visio中不借助公式编辑器在字母上方打波浪线

热门文章

  1. 紧随大数据浪潮:爬虫工具采集同花顺圈子评论教程
  2. 华为计算机技能,华为P20手机新技能,电脑模式你玩过吗?有了它迅速实现
  3. arcgis engine 入门难点——什么是接口查询(QueryInterface)
  4. 组装微型计算机需要哪些硬件设备,组装电脑需要哪些配件
  5. 2021年度总结 -- 致自己也致你们
  6. VS2010 英文旗舰版 MFC 生成安装程序报错
  7. 抓取万方数据内海量论文
  8. android 解决asset下面文件太大报错问题
  9. python在一个画布上画多个子图
  10. Qt:setEnabled()和setClickable()