android动态代理学习笔记
来源:互联网 发布:sql字段前加内容 db2 编辑:程序博客网 时间:2024/06/05 18:37
参考博客1:http://android.jobbole.com/83143/
另外,通过自动化测试工具 Mockito 也不能mock类SystemClock,因为它是final修饰的。所以,接下来考虑使用动态代理的方式来做,即希望可以将SystemClock这个类的getCurrentTimeMills进行篡改,让它返回指定的时间。
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
参考博客2:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html
近期在做自动化测试开发,有个功能是mock系统时间。但是我们知道只有系统进程才有permission通过SystemClock来设置系统时间:
SystemClock.setCurrentTimeMillis(Long timeMills)
另外,通过自动化测试工具 Mockito 也不能mock类SystemClock,因为它是final修饰的。所以,接下来考虑使用动态代理的方式来做,即希望可以将SystemClock这个类的getCurrentTimeMills进行篡改,让它返回指定的时间。
本次博客仅仅记录学习过程,至于mock系统时间的实现,后序更新。
静态代理:由程序员编写,在程序运行前,代理类.class已经存在。
动态代理:通过jdk提供的api编写,由反射机制自动生成。
关于静态代理,代码举例如下所示:Dog:接口;Samo:接口实现类 ;SamoProxy : 代理类。
public interface Dog { //接口 public void run();}
public class Samo implements Dog { //接口实现类 @Override public void run() { System.out.println("Samo is running !"); }}
public class SamoProxy extends Samo { //静态代理类 private Samo samo; public SamoProxy(Samo obj){ samo = obj; } @Override public void run() { System.out.println("before run"); samo.run(); System.out.println("afer run"); }}
public class RunTest { //测试代码 public static void main(String[] args){ Samo samo = new Samo(); //萨摩run samo.run(); //代理萨摩run new SamoProxy(samo).run(); }}
以上是静态代理测试、学习过程。接下来介绍动态代理:
动态代理涉及一个关键类和一个关键接口:
关键接口:InvocationHandler,关键类:Proxy。
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;}Object proxy :被代理的类;Method method :要调用的函数。 Object[] args:函数的参数。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentExceptionClassLoader loader:类加载器 Class<?>[] interfaces:得到全部的接口 InvocationHandler h:得到InvocationHandler接口的子类实例
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
以下是几个关键类:
DSamoProxy :萨摩动态代理类
import java.lang.reflect.*;/** * Created by Joe on 2016/10/15. */public class DSamoProxy implements java.lang.reflect.InvocationHandler { private Object samo; public DSamoProxy(Object obj){ samo = obj; } public Object getProxy(){ //jdk提供的动态代理,只能传参 interface ,返回的是萨摩代理!!很关键 return Proxy.newProxyInstance(samo.getClass().getClassLoader(),samo.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("before running"); result = method.invoke(samo,args); System.out.println("after running"); return result; }}
public class DRunTest { public static void main(String[] args) { DSamoProxy proxy = new DSamoProxy(new Samo()); Dog samoProxy = (Dog) proxy.getProxy(); samoProxy.run(); }}
以上的动态代理实现较为简单,但是如果要代理SDK中不是public的类,或者是@hide隐藏的类或者是@hide隐藏的方法呢?那就涉及到反射机制。接下来,参考博客1给出以下笔记:
0 0
- android动态代理学习笔记
- 动态代理学习笔记
- 动态代理学习笔记
- 动态代理学习笔记
- 动态代理学习笔记
- 静态代理和动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- 学习笔记_jdk动态代理
- java动态代理学习笔记
- java动态代理学习笔记
- Java 动态代理学习笔记
- Java动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- 小白日记32:kali渗透测试之Web渗透-扫描工具-QWASP_ZAP
- 进程控制
- UML学习笔记
- BZOJ3192: [JLOI2013]删除物品 树状数组
- 大数据与云计算笔记[二]:安全加密
- android动态代理学习笔记
- 数字货币怎么制作
- Java IO
- c++的传值与引用
- (Java)小数点处理
- 【LeetCode】50. Pow(x, n)
- 微信分享域名防屏蔽 防微信拦截网址系统
- Andriod5.0&&Andriod6.0
- android常用工具类总结