反射调用被标记为@hide的API

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

复制代码

转载于:https://juejin.im/post/5c90b1dbf265da610b3a040b

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的@override注解是用来标记方法覆盖父类或接口中的方法。通过使用@override注解,我们可以确保子类或实现类正确地覆盖了父类或接口中的方法,从而避免出现潜在的错误。 反射Java中的一种机制,用于动态地调用对象的方法或访问对象的属性。通过反射,我们可以在运行时动态地获取类的信息,并调用类中的方法。 如果想要用反射调用外部方法,我们可以按照以下步骤进行操作: 1. 获取目标类的Class对象:使用Class.forName()方法获取目标类的Class对象。 2. 实例化目标类的对象:使用Class对象的newInstance()方法实例化目标类的对象。 3. 获取目标方法的Method对象:使用Class对象的getMethod()方法获取目标方法的Method对象。 4. 调用目标方法:使用Method对象的invoke()方法调用目标方法。 下面是一个示例代码,用于演示如何使用反射调用外部方法: ```java public class ReflectExample { public static void main(String[] args) throws Exception { // 获取目标类的Class对象 Class<?> targetClass = Class.forName("com.example.TargetClass"); // 实例化目标类的对象 Object targetObject = targetClass.newInstance(); // 获取目标方法的Method对象 Method targetMethod = targetClass.getMethod("methodName", parameterTypes); // 调用目标方法 targetMethod.invoke(targetObject, arguments); } } ``` 需要注意的是,在使用反射调用外部方法时,需要提供目标方法的名称、参数类型以及参数值。通过上述步骤,我们可以使用反射机制动态地调用外部方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值