您的位置:首页 > 移动开发 > Android开发

android中反射技术使用实例

2016-05-22 14:36 471 查看
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。反射 是 Java程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。Java
的反射机制的实现要借助于4个类:class,Constructor,Field,Method;其中class代表的时类对 象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。
1.通过反射技术可以访问到其他包名下数据方法等,这些为一些APK换皮肤提供了方便

首先初始化skinContext

?
可以通过下面的方法访问到指定包名下的资源ID

?
最后通过资源ID和skinContext可以访问到指定包下的所有资源,例如要访问layout

?
注:换皮肤思路详见:http://blog.csdn.net/tangnengwu/article/details/22801107

2. 访问android 隐藏的API

Toast信息框的关闭是由系统管理的,因为hide方法是隐藏的开发者没有办法直接调用,这种情况下可以用发射机制获取这个方法,创建一个显示和隐藏都由开发者控制的Toast信息框。

?
显示toast:

?
隐藏toast:
toast.hide();

注意在4.0以上的版本中,还需要对Toast 中的View进行处理,如代码中所示

3. 修改某些“不可改” 的系统资源

ListView组件没有提供修改快速滑块图像的API,因此不能直接修改,但可通过反射实现

?
?
FastScroller.mThunbDrawable变量保存了快速滑块图像,但首先要获取AbsListView.mFastScroller变量

?
?
使用快速滑块
效果图如下:



往sim卡里面复制短信


访问API隐藏的方法:
往sim卡里面复制短信的时候,需要用到方法
copyMessageToIcc
,但是在apk中是hide的,那么我们就需要用反射的方法来获取出这个方法了:
// smsManager.copyMessageToIcc(null, pdu, 1);


public void insert() {

SmsManager smsManager = SmsManager.getDefault();

byte[] smsc = new byte[2];

smsc[0] = 0x1;

smsc[1] = 0x2;

String clxs = "123";

byte[] pdu = hexStringToBytes("200d91683119603514f90000313021023025230331d90c");

Class<?> c;

try {

c = Class.forName("android.telephony.SmsManager");

Method[] ms = c.getMethods();

for (Method m : ms) {

System.out.println(m.getName());

Class<?>[] cx = m.getParameterTypes();

for (Class<?> cx1 : cx)

System.out.println(cx1.getName());

System.out.println(m.getReturnType());

}

Method m = c.getMethod("copyMessageToIcc", new Class[] {

byte[].class, byte[].class, int.class });

Object s = m.invoke(SmsManager.getDefault(), null, pdu, 1);

} catch (Exception e) {

e.printStackTrace();

}

// smsManager.copyMessageToIcc(null, pdu, 1);

}

总结:

Java中的反射机制,被称为Reflection,它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的内部信息,包括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 construct等

反射中一些参数函数的理解

MainActivity如下:

package cn.testreflect;

  import java.lang.reflect.Constructor;

  import java.lang.reflect.Field;

  import java.lang.reflect.Method;

  import android.os.Bundle;

  import android.app.Activity;

  /**

  * Demo描述:

  * Android中Java反射技术的使用示例

  * 在Java中描述字节码文件(xxx.class)的类叫Class

  * 反射的过程可视为剖析Class的过程

  */

  public class MainActivity extends Activity {

  @Override

  protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.main);

  init();

  }

  private void init(){

  try {

  /**

  * 1 反射出无参的构造方法并得到对象

  * 注意:

  * 1 在Class.forName()中应该传入含有包名的类全名

  * 2 newInstance()方法的本质是调用类的无参Public构造方法

  */

  String className1="cn.testreflect.Worker";

  Class clazz1=Class.forName(className1);

  Object object1=clazz1.newInstance();

  System.out.println("object1.toString()="+object1.toString());

  /**

  * 2 反射出带参数的构造方法并得到对象

  */

  String className2="cn.testreflect.Worker";

  Class clazz2=Class.forName(className2);

  Constructor constructor1=clazz2.getConstructor(int.class,String.class);

  Object object2=constructor1.newInstance(18,"小明");

  System.out.println("object2.toString()="+object2.toString());

  /**

  * 3 获取类的私有字段

  * 注意:

  * 获取共有字段应调用clazz3.getField(name)方法

  */

  String className3="cn.testreflect.Worker";

  Class clazz3=Class.forName(className3);

  Field ageField1=clazz3.getDeclaredField("age");

  System.out.println("ageField1="+ageField1);

  /**

  * 4 获取和更改某个对象的私有字段

  * 即模拟get()和set()方法

  */

  String className4="cn.testreflect.Worker";

  Class clazz4=Class.forName(className4);

  Field ageField2=clazz4.getDeclaredField("age");

  Object object4=constructor1.newInstance(18,"小明");

  //取消访问私有字段的合法性检查

  ageField2.setAccessible(true);

  //获取对象的私有字段

  Object ageObject4=ageField2.get(object4);

  System.out.println("ageObject4="+ageObject4);

  //再更改对象的私有字段的值

  ageField2.set(object4, 9527);

  //重新获得

  Object ageObject5=ageField2.get(object4);

  System.out.println("ageObject5="+ageObject5);

  /**

  * 5 调用对象的带参数的方法

  */

  String className5="cn.testreflect.Worker";

  Class clazz5=Class.forName(className5);

  Method method=clazz5.getMethod("printMessage",

String.class,int.class,int.class);

  Object object5=clazz5.newInstance();

  method.invoke(object5, "周星星",50,9527);

  } catch (Exception e) {

  System.out.println(e.toString());

  }

  }

  }

复制代码
  Worker如下:

package cn.testreflect;

  public class Worker {

  private int age;

  private String name;

  public Worker() {

  super();

  System.out.println("---> public Worker(){ }");

  }

  public Worker(int age, String name) {

  super();

  this.age = age;

  this.name = name;

  System.out.println("---> public Worker(int age, String name){ }");

  }

  public int getAge() {

  return age;

  }

  public void setAge(int age) {

  this.age = age;

  }

  public String getName() {

  return name;

  }

  public void setName(String name) {

  this.name = name;

  }

  @Override

  public String toString() {

  return "Worker [age=" + age + ", name=" + name + "]";

  }

  public void printMessage(String name,int age,int salary){

  System.out.println("name="+name+",age="+age+",salary="+salary);

  }

  }

复制代码
  main.xml如下:

  xmlns:tools="http://schemas.android.com/tools"

  android:layout_width="match_parent"

  android:layout_height="match_parent"

  >  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:text="Android中Java反射技术的使用"

  android:layout_centerInParent="true"/>

MainActivity如下:

java代码

package cn.testreflect;

  import java.lang.reflect.Constructor;

  import java.lang.reflect.Field;

  import java.lang.reflect.Method;

  import android.os.Bundle;

  import android.app.Activity;

  /**

  * Demo描述:

  * Android中Java反射技术的使用示例

  * 在Java中描述字节码文件(xxx.class)的类叫Class

  * 反射的过程可视为剖析Class的过程

  */

  public class MainActivity extends Activity {

  @Override

  protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.main);

  init();

  }

  private void init(){

  try {

  /**

  * 1 反射出无参的构造方法并得到对象

  * 注意:

  * 1 在Class.forName()中应该传入含有包名的类全名

  * 2 newInstance()方法的本质是调用类的无参Public构造方法

  */

  String className1="cn.testreflect.Worker";

  Class clazz1=Class.forName(className1);

  Object object1=clazz1.newInstance();

  System.out.println("object1.toString()="+object1.toString());

  /**

  * 2 反射出带参数的构造方法并得到对象

  */

  String className2="cn.testreflect.Worker";

  Class clazz2=Class.forName(className2);

  Constructor constructor1=clazz2.getConstructor(int.class,String.class);

  Object object2=constructor1.newInstance(18,"小明");

  System.out.println("object2.toString()="+object2.toString());

  /**

  * 3 获取类的私有字段

  * 注意:

  * 获取共有字段应调用clazz3.getField(name)方法

  */

  String className3="cn.testreflect.Worker";

  Class clazz3=Class.forName(className3);

  Field ageField1=clazz3.getDeclaredField("age");

  System.out.println("ageField1="+ageField1);

  /**

  * 4 获取和更改某个对象的私有字段

  * 即模拟get()和set()方法

  */

  String className4="cn.testreflect.Worker";

  Class clazz4=Class.forName(className4);

  Field ageField2=clazz4.getDeclaredField("age");

  Object object4=constructor1.newInstance(18,"小明");

  //取消访问私有字段的合法性检查

  ageField2.setAccessible(true);

  //获取对象的私有字段

  Object ageObject4=ageField2.get(object4);

  System.out.println("ageObject4="+ageObject4);

  //再更改对象的私有字段的值

  ageField2.set(object4, 9527);

  //重新获得

  Object ageObject5=ageField2.get(object4);

  System.out.println("ageObject5="+ageObject5);

  /**

  * 5 调用对象的带参数的方法

  */

  String className5="cn.testreflect.Worker";

  Class clazz5=Class.forName(className5);

  Method method=clazz5.getMethod("printMessage",

String.class,int.class,int.class);

  Object object5=clazz5.newInstance();

  method.invoke(object5, "周星星",50,9527);

  } catch (Exception e) {

  System.out.println(e.toString());

  }

  }

  }

复制代码
  Worker如下:

package cn.testreflect;

  public class Worker {

  private int age;

  private String name;

  public Worker() {

  super();

  System.out.println("---> public Worker(){ }");

  }

  public Worker(int age, String name) {

  super();

  this.age = age;

  this.name = name;

  System.out.println("---> public Worker(int age, String name){ }");

  }

  public int getAge() {

  return age;

  }

  public void setAge(int age) {

  this.age = age;

  }

  public String getName() {

  return name;

  }

  public void setName(String name) {

  this.name = name;

  }

  @Override

  public String toString() {

  return "Worker [age=" + age + ", name=" + name + "]";

  }

  public void printMessage(String name,int age,int salary){

  System.out.println("name="+name+",age="+age+",salary="+salary);

  }

  }

复制代码
  main.xml如下:

  xmlns:tools="http://schemas.android.com/tools"

  android:layout_width="match_parent"

  android:layout_height="match_parent"

  >  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:text="Android中Java反射技术的使用"

  android:layout_centerInParent="true"/>

复制代码

原文链接:http://www.eyeandroid.com/thread-17067-1-1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: