Android反射机制实例参考(转载)

对程序员来说,放假只是换了一个写代码的地方! 
看一下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);
	}
}
<pre name="code" class="java">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

点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值