Android反射机制范例
Android反射机制实例
对程序员来说,放假只是换了一个写代码的地方!
看一下Java(Android)里面的反射怎么用:
一、先来定义两个类(一个父类,一个子类):
以上两个类只是为了测试,不用关心具体实现代码,只要知道有private变量和方法,protected变量和方法,public变量和方法。重点在下面:
二、利用反射,调用上面的类:
三、最后贴一个Android里面的具体事例:
关于反射的使用,基本就这些了,代码注释已经很详细了,就不需要多余的说明了,想了解反射的原理,建议大家看源码!
参考:http://www.cnblogs.com/crazypebble/archive/2011/04/13/2014582.html
对程序员来说,放假只是换了一个写代码的地方!
看一下Java(Android)里面的反射怎么用:
一、先来定义两个类(一个父类,一个子类):
package com.zwq.test; public abstract class Person { String name = ""; private int age = 0; public int fPubVar = 0; abstract void getPhone(); public Person() { System.out.println("I am Farther"); } int myAge() { return 50; } String myName() { return "Father"; } public void callSun() { getPhone(); priMethod(25); } private void priMethod(Integer a) { age = a; System.out.println("I am priMethod , Dont call me! age " + age); } /** * @hide */ public void hideMethod(String name) { System.out.println("I am hideMethod , Dont call me! name:" + name + " age:" + age); } }
package com.zwq.test; import java.util.Observable; import java.util.Observer; public class Man extends Person implements Observer { private int age = 0; private String var1 = "I am var1"; public int var2 = 20; public Man() { System.out.println("I am Man" + var1); age = 20; } public int myAge() { return 28; } public String myName() { return "Jerome"; } private void getName(){ System.out.println("I am Jerome"); } /** *@hide */ private void getAge(){ System.out.println("I am "+age); } @Override void getPhone() { System.out.println("I am sun , My age is " + age + "___" + var2); } @Override public void update(Observable o, Object arg) { } }
以上两个类只是为了测试,不用关心具体实现代码,只要知道有private变量和方法,protected变量和方法,public变量和方法。重点在下面:
二、利用反射,调用上面的类:
package com.zwq.test; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Main { public static void main(String[] args) { getInfo(); callSpuerMethod(); callCurrentMethod(); callOtherMethod(); } static void getInfo() { Man r = new Man(); Class<?> temp = r.getClass(); try { System.out.println("反射类中所有公有的属性"); Field[] fb = temp.getFields(); for (int j = 0; j < fb.length; j++) { Class<?> cl = fb[j].getType(); System.out.println("fb:" + cl + "___" + fb[j].getName()); } System.out.println("反射类中所有的属性"); Field[] fa = temp.getDeclaredFields(); for (int j = 0; j < fa.length; j++) { Class<?> cl = fa[j].getType(); System.out.println("fa:" + cl + "____" + fa[j].getName()); } System.out.println("反射类中所有的方法"); Method[] fm = temp.getMethods(); for (int i = 0; i < fm.length; i++) { System.out.println("fm:" + fm[i].getName() + "____" + fm[i].getReturnType().getName()); } System.out.println("反射类中所有的接口"); Class<?>[] fi = temp.getInterfaces(); for (int i = 0; i < fi.length; i++) { System.out.println("fi:" + fi[i].getName()); } System.out.println("反射类中私有属性的值"); Field f = temp.getDeclaredField("var1"); f.setAccessible(true); String i = (String) f.get(r); System.out.println(i); } catch (Exception e) { e.printStackTrace(); } } /** * 修复父类变量,调用父类方法 */ static void callSpuerMethod() { Man r = new Man(); try { // 修改私有变量; Field f = r.getClass().getSuperclass().getDeclaredField("age"); f.setAccessible(true); f.set(r, 20); // 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod; Method mp = r.getClass().getSuperclass() .getDeclaredMethod("priMethod", Integer.class); mp.setAccessible(true); mp.invoke(r, 18); // 调用隐藏方法 Method m = r.getClass().getSuperclass() .getMethod("hideMethod", String.class); m.setAccessible(true); m.invoke(r, "Jerome"); } catch (Exception e) { e.printStackTrace(); } } /** * 修复子类变量,调用子类方法 */ static void callCurrentMethod() { Man r = new Man(); try { // 修改私有变量; Field f = r.getClass().getDeclaredField("age"); f.setAccessible(true); f.set(r, 20); // 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod; Method mp = r.getClass().getDeclaredMethod("getName"); mp.setAccessible(true); mp.invoke(r); // 调用隐藏私有方法 Method m = r.getClass().getDeclaredMethod("getAge"); m.setAccessible(true); m.invoke(r); } catch (Exception e) { e.printStackTrace(); } } /** * 用Class.forName加载类及实例化 */ static void callOtherMethod() { try { // Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象 // Class.forName(xxx.xx.xx) 的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段 Class<?> cl = Class.forName("com.zwq.test.Man"); Object r = cl.newInstance(); // 修改私有变量; Field f = cl.getDeclaredField("age"); f.setAccessible(true); f.set(r, 20); // 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod; Method mp = cl.getDeclaredMethod("getName"); mp.setAccessible(true); mp.invoke(r); // 调用隐藏私有方法 Method m = cl.getDeclaredMethod("getAge"); m.setAccessible(true); m.invoke(r); } catch (Exception e) { e.printStackTrace(); } } }
三、最后贴一个Android里面的具体事例:
/** * 获得包的大小 * * @param pkgName * @throws Exception */ public void queryPacakgeSize(String pkgName) throws Exception { if (pkgName != null) { // 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfo PackageManager pm = getPackageManager(); // 得到pm对象 try { // 通过反射机制获得该隐藏函数 Method getPackageSizeInfo = pm.getClass().getDeclaredMethod( "getPackageSizeInfo", String.class, IPackageStatsObserver.class); // 调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数 getPackageSizeInfo.invoke(pm, pkgName, new PkgSizeObserver()); // 停止主线程让PackageStats对象获得数据 Thread.sleep(8); } catch (Exception ex) { // Log.e("TAG", "NoSuchMethodException") ; ex.printStackTrace(); throw ex;// 抛出异常 } } }
关于反射的使用,基本就这些了,代码注释已经很详细了,就不需要多余的说明了,想了解反射的原理,建议大家看源码!
参考:http://www.cnblogs.com/crazypebble/archive/2011/04/13/2014582.html