P之前的Android Java Framework中,有些被标记为@hide的API可以通过反射来访问。但P开始对此方式作了限制。 例如访问StorageManager的getVolumeList()
frameworks/base/core/java/android/os/storage/StorageManager.java
复制代码
/** {@hide} */
public @NonNull StorageVolume[] getVolumeList() {
return getVolumeList(mContext.getUserId(), 0);
}
复制代码
可以通过反射调用
StorageManager mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
Object[] arrs = (Object[]) SdkReflectUtils.invokeMethod(mStorageManager,"getVolumeList",null,null);
for (int i = 0; i < arrs.length; i++) {
StorageVolume volume = (StorageVolume) arrs[i];
Log.d(TAG,",volume "+volume.toString());
}
复制代码
反射工具类
反射相关的类主要有Class、Constructor、Field、Method、Modifier。
public class SdkReflectUtils {
public static Class getClazz(String className){
Class clazz = null;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return clazz;
}
public static Object newInstance(Class clazz,Class[] argsType, Object... args){
Object instance = null;
try {
Constructor constructor = clazz.getConstructor(argsType);
constructor.setAccessible(true);
instance = constructor.newInstance(args);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return instance;
}
public static Object getFieldValue(Object object,String name){
Object fieldValue = null;
try {
Field field = object.getClass().getDeclaredField(name);
field.setAccessible(true);
fieldValue = field.get(object);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return fieldValue;
}
public static void setFieldValue(Object object,String name, Object value){
try {
Field field = object.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(object, value);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static Object getStaticFieldValue(Class clazz, String name){
Object fieldValue = null;
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
fieldValue = field.get(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return fieldValue;
}
public static void setStaticFieldValue(Class clazz,String name, Object value){
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(null, value);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static Object invokeMethod(Object o, String name, Class[] argsType,Object... args){
Object result = null;
try {
Method method = o.getClass().getDeclaredMethod(name,argsType);
method.setAccessible(true);
result = method.invoke(o,args);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
public static Object invokeStaticMethod(Class clazz, String name, Class[] argsType,Object... args){
Object result = null;
try {
Method method = clazz.getDeclaredMethod(name,argsType);
method.setAccessible(true);
result = method.invoke(null,args);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
}
复制代码
测试类
public class Plane {
private static final String TAG = "Plane";
private static String STATIC_FILE = "STATIC_FILE";
private String name;
private int no;
public Plane(String name, int no) {
this.name = name;
this.no = no;
Log.d(TAG,"2 args");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String printStr(String appendStr,int appendInt){
String str = "I am a normal method appendStr:"+appendStr +",appendInt "+ appendInt+",value="+toStr()+STATIC_FILE;
Log.d(TAG,str);
return str;
}
public static String printStaticStr(String appendStr,int appendInt){
String str = "I am a static method appendStr:"+appendStr +",appendInt "+ appendInt+",value="+STATIC_FILE;
Log.d(TAG,str);
return str;
}
private String toStr(){
return "name:"+name+",no:"+no;
}
public static class StaticInner{
private String type;
public StaticInner(String typ){
type = typ;
}
public void printInner(){
Log.d(TAG,"printInner Inner "+type);
}
public static void printStaticInner(String arg){
Log.d(TAG,"printStaticInner "+arg);
}
}
public class NormalInner{
private String type;
public NormalInner(String typ){
type = typ;
Log.d(TAG," NormalInner ==="+type);
}
public void printInner(String norArg){
Log.d(TAG,norArg+",printInner NormalInner "+type);
}
}
}
复制代码
用法
//访问成员方法
Class clazz = SdkReflectUtils.getClazz("com.test.ref.Plane");
Class[] argsType = {String.class,int.class};
Object[] args = {"China",70};
Object instance = SdkReflectUtils.newInstance(clazz,argsType,args);
Class[] mArgsType = {String.class,int.class};
Object[] mArgs = {"append str",100000};
Object result = SdkReflectUtils.invokeMethod(instance,"printStr",mArgsType,mArgs);
Log.d(TAG,"normalmethod "+result);
//访问静态方法
Object staticResult = SdkReflectUtils.invokeStaticMethod(clazz,"printStaticStr",mArgsType,mArgs);
Log.d(TAG,"staticmethod "+staticResult);
//修改成员属性
SdkReflectUtils.setFieldValue(instance,"name","Russia");
SdkReflectUtils.setFieldValue(instance,"no",111);
Object setField = SdkReflectUtils.invokeMethod(instance,"printStr",mArgsType,mArgs);
Log.d(TAG,"setFieldValue "+setField);
//访问静态熟悉
SdkReflectUtils.setStaticFieldValue(clazz,"STATIC_FILE","STATIC_FILE_MAIN");
Object getStaticFieldV = SdkReflectUtils.getStaticFieldValue(clazz,"STATIC_FILE");
Object setStaticField = SdkReflectUtils.invokeMethod(instance,"printStr",mArgsType,mArgs);
Log.d(TAG,getStaticFieldV+",setStaticField "+setStaticField);
//访问静态内部类的静态方法
Class staticClazz = SdkReflectUtils.getClazz("com.test.ref.Plane$StaticInner");
Class[] argTpe = {String.class};
Object[] ar = {"main"};
Object statinner = SdkReflectUtils.invokeStaticMethod(staticClazz,"printStaticInner",argTpe,ar);
Log.d(TAG,",statinner "+statinner);
//访问静态内部类的成员方法
Class[] stainargt = {String.class};
Object[] stainval = {"sta"};
Object staIner = SdkReflectUtils.newInstance(staticClazz, stainargt,stainval);
Class[] stinC = {};
Object[] stinV = {};
SdkReflectUtils.invokeMethod(staIner,"printInner",stinC,stinV);
//访问非静态内部类的成员方法
Class normalInnerClz = SdkReflectUtils.getClazz("com.test.ref.Plane$NormalInner");
Class[] norTp = {clazz,String.class};
Object[] norV = {instance,"norIn"};//引用外部类实例,构造内部类实例
Object norIn =SdkReflectUtils.newInstance(normalInnerClz,norTp,norV);
Class[] norMTp = {String.class};
Object[] norMV = {"normn"};
SdkReflectUtils.invokeMethod(norIn,"printInner",norMTp,norMV);
复制代码