详解Java编程中的反射在Android开发中的应用_Android

反射定义

“反射”(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为。
为何需要反射

反射带来的好处包括:

  •     在运行时检测对象的类型。
  •     动态构造某个类的对象。
  •     检测类的属性和方法。
  •     任意调用对象的方法。
  •     修改构造函数、方法、属性的可见性。

反射方法Method
getDeclaredMethod方法

声明如下:

public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

解释:

    返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定已声明方法。
    1. name : 是一个String,它指定所需方法的简称。
    2. parameterTypes:是一个Class对象的变长数组,它按声明顺序标识该方法的形参类型。

注意:
getDeclaredMethod获取该类声明的public方法或者protected方法,但是不包括继承的方法。
getMethod方法

声明如下:

public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

解释:

    返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定公共成员方法。
    1. name : 是一个String,它指定所需方法的简称。
    2. parameterTypes:是一个Class对象的变长数组,它按声明顺序标识该方法的形参类型。

参数解释

name参数就不需要解释了,就是调用类的方法名称。

可能很多同学刚接触这个方法的时候,会对parameterTypes参数产生疑问,例如这个参数为什么是Class泛型变长数组,其实举个例子就很好理解了。

假设我们要反射的方法有4个参数,函数原型如下:

public void printInfo(String str, int iNum, double dNum, long i);

那我们通过返回获取这个Method对象的时候,传的parameterTypes如下所示:

getMethod("printInfo", String.class, int.class, double.class, long.class);

所以,parameterTypes其实就是对方法形参的类型抽象。
invoke方法

声明如下:

public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException

解释:

    Method类的invoke(Object obj, Object… args)方法接收的参数必须为对象。其中:
    1. obj : 从中调用底层方法的对象。
    2. args :用于方法调用的参数。

Android 反射应用

我们知道,Android有些类是没有在SDK中开放的,例如你需要获取系统属性,需要调用到SystemProperties类的get方法,但是这个类并没有在SDK中公开,我们可以在Android源码中查看一下这个类:

package android.os;

import java.util.ArrayList;

import android.util.Log;

/**
 * Gives access to the system properties store. The system properties
 * store contains a list of string key-value pairs.
 *
 * {@hide}
 */
public class SystemProperties
{
  // 省略具体实现代码
  /**
 * Get the value for the given key.
 * @return an empty string if the key isn't found
 * @throws IllegalArgumentException if the key exceeds 32 characters
 */
 public static String get(String key) {
  if (key.length() > PROP_NAME_MAX) {
   throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  }
  return native_get(key);
 }
}

可以看到,这个前面有一个@hide标签,所以这个类是没法直接在代码中调用的。

但是,在Android应用中,很多时候我们需要获取到手机类型属性(ro.product.model)。所以,这个时候,我们就需要在应用层反射SystemProperties类,调用get方法。具体实现源码如下:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.util.Log;

public class SystemProperties {
 public static String get(String key) {
  String value = "";
  Class<?> cls = null;

  try {
   cls = Class.forName("android.os.SystemProperties");
   Method hideMethod = cls.getMethod("get", String.class);
   Object object = cls.newInstance();
   value = (String) hideMethod.invoke(object, key);
  } catch (ClassNotFoundException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (NoSuchMethodException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (InstantiationException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (IllegalAccessException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (IllegalArgumentException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (InvocationTargetException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  }

  return value;
 }

}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
android
android网络编程详解、android中jni编程详解、android应用开发详解、android项目开发详解、android dlna开发详解,以便于您获取更多的相关知识。

时间: 2025-01-02 20:35:21

详解Java编程中的反射在Android开发中的应用_Android的相关文章

详解Java编程中的反射在Android开发中的应用

反射定义 "反射"(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为. 为何需要反射 反射带来的好处包括: 在运行时检测对象的类型.     动态构造某个类的对象.     检测类的属性和方法.     任意调用对象的方法.     修改构造函数.方法.属性的可见性. 反射方法Method getDeclaredMethod方法 声明如下: public Method getDeclaredMethod(String name, Class<?>...

详解Java编程中对象的序列化_java

1. 什么是Java对象序列化 Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长.但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象.Java对象序列化就能够帮助我们实现该功能. 使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象.必须注意地是,对象序列化保存的是对象的"状态",

详解Java编程中线程的挂起、恢复和终止的方法_java

有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线程机制在Java 2和早期版本中有所不同.尽管你运用Java 2的途径编写代码,你仍需了解这些操作在早期Java环境下是如何完成的.例如,你也许需要更新或维护老的代码.你也需要了解为什么Java 2会有这样的变化.因为这些原因,下面内容描述了执行线程控制的原始方法,接着是Java 2的方法. Jav

详解Java编程中线程同步以及定时启动线程的方法_java

使用wait()与notify()实现线程间协作 1. wait()与notify()/notifyAll()调用sleep()和yield()的时候锁并没有被释放,而调用wait()将释放锁.这样另一个任务(线程)可以获得当前对象的锁,从而进入它的synchronized方法中.可以通过notify()/notifyAll(),或者时间到期,从wait()中恢复执行. 只能在同步控制方法或同步块中调用wait().notify()和notifyAll().如果在非同步的方法里调用这些方法,在运

详解Java编程中的策略模式_java

策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理.策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类.用一句话来说,就是:"准备一组算法,并将每一个算法封装起来,使得它们可以互换".下面就以一个示意性的实现讲解策略模式实例的结构. 这个

详解Java编程中对线程的中断处理_java

1. 引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时--都需要通过一个线程去取消另一个线程正在执行的任务.Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制. 如果对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此.中断机制是如何工作的?捕获或检测到中断后,是抛出InterruptedException还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.st

详解Java编程中包package的内容与包对象的规范_java

包的内容包的内容应该仔细设计,使其只包含在功能上相关的类和接口.包中的类可以自由地访问该包中其他类的非私有成员,有些类甚至可能有足够的权限去访问其他类的内部细节,为了避免这样的类对类成员进行误操作,我们需要对类成员进行保护.任何没有被声明为private的成员都可以被同一个包中的其他所有类型访问,所以任何不相关的类之间的藕合程度都可能会比我们所期望的程度高. 包还为寻找有用的接口和类的程序员提供了逻辑分组的功能.由不相关的类组成的包使程序员很难分辨出哪些接口和类是有用的,而类的逻辑分组可以帮助程

详解Java编程中向量(Vector)的应用_java

Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能. 向量和数组相似,都可以保存一组数据(数据列表).但是数组的大小是固定的,一旦指定,就不能改变,而向量却提供了一种类似于"动态数组"的功能,向量与数组的重要区别之一就是向量的容量是可变的. 可以在向量的任意位置插入不同类型的对象,无需考虑对象的类型,也无需考虑向量的容量. 向量和数组分别适用于不同的场合,一般来说,下列场合更适合于使用向量: 如果需要频繁进行对象的插入和删除工作,或者因为需要处理的对

详解Java编程中面向字符的输出流_java

面向字符的输出流都是类 Writer 的子类,其类层次结构如图所示. 下表列出了 Writer 的主要子类及说明. 使用 FileWriter 类写入文件 FileWriter 类是 Writer 子类 OutputStreamWriter 类的子类,因此 FileWriter 类既可以使用 Writer类的方法也可以使用 OutputStreamWriter 类的方法来创建对象. 在使用 FileWriter 类写入文件时,必须先调用 FileWriter()构造方法创建 FileWriter