`

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);
	}
}



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
0
0
分享到:
评论

相关推荐

    android 使用反射机制操作数据库 插入 查询

    android 使用反射机制操作数据库 插入 查询 十分便捷 代码内已有实例 简单明了

    Android入门之Gallery用法实例解析

    本文实例中的Gallery的用法,主要实现用反射机制来动态读取资源中的图片。 该实例代码运行的效果图如下:   main.xml源码如下: &lt;?xml version=1.0 encoding=utf-8?&gt; &lt;LinearLayout xmlns:android=...

    Android编程实现通过反射获取资源Id的方法

    主要介绍了Android编程实现通过反射获取资源Id的方法,结合实例形式分析了Android反射机制操作资源的相关实现技巧,需要的朋友可以参考下

    AndroidSQLite封装类

    利用Java反射机制实现Android数据库操作的封装,不用频繁对数据库进行操作,定义好一个实例类后,只需新增一行代码就能实现根据类名映射出相关的数据表名,列名,和相关的增删改查工作。类似于J2EE中的 Hibernate...

    Android的Gallery控件处理图片特效实例代码

    Gallery控件是个很不错的看图控件,大大减轻了开发者对于看图功能的开发,而且效果也比较美观。本文介绍Gallery的用法,用反射机制来动态读取资源中的图片。

    Android 监听屏幕是否锁屏的实例代码

    2)如果要在屏幕状态发生改变之前就想获取屏幕状态,可以通过反射机制调用PowerManager的isScreenOn方法 。 具体实现,见代码: 直接上代码: 1.定义一个接收广播的类 package com.app.lib; import android.content...

    Android入门之Gallery+ImageSwitcher用法实例解析

    继上一篇介绍了如何使用Gallery控件之后,本文就来讲...本例子依然使用JAVA的反射机制来自动读取资源中的图片。 main.xml的源码如下: &lt;?xml version=1.0 encoding=utf-8?&gt; &lt;RelativeLayout xmlns:android=

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--aidl之结合反射获取应用缓存大小等空间占用 |--aidl调用系统service未公开的方法挂电话 |--aidl调用系统未公开的方法代码示例2 |--android dp和px之间转换 |--android INSTALL_PARSE_FAILED_MANIFEST_MALFORMED |...

    Android编程获取通知栏高度的方法

    这里通过反射机制获取通知栏高度 通知栏高度写在dimen文件中: public static int getStatusBarHeight(Context context){ Class&lt;?&gt; c = null; Object obj = null; Field field = null; int x = 0, ...

    Android开发资料合集--续

    比之前的合集更丰富详细的细节;没有最新只有更新! 1、建立GPRS连接 4 2、判断网络状态是否可用 4 ...102、反射机制 148 103、JS 148 104、TextView多行末尾显示省略号 148 105、竖直显示的textView 153

    eclipse安卓开发必备工具

    } } 发现居然也能调用成功,当时很惊讶,反射机制平时在以前的项目中也常使用,但不能构造只有私有构造函数的类。 自己做了一个简单例子: package study.spring.bean; import java.lang.reflect.Constructor; ...

Global site tag (gtag.js) - Google Analytics