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

在Android Java Framework中,P版本之前可通过反射访问标记为@hide的API,P版本开始对此作了限制,如访问StorageManager的getVolumeList()。还介绍了反射工具类,涉及Class、Constructor等相关类,以及测试类和用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值