android 反射使用

1、在我们开发过程中可能会遇到某些类中的方法或变量无法使用,例如加了/** {@hide} */注释的,就是一些隐藏的方法。如果我们用反射就可以轻松调用了。

2、虽然如此但反射也有缺点:

* 因为是动态执行的,效率自然没有预编译时引用现有的库效率高,就像平时我们Win32开发时,可以不用h文件,直接通过GetProcAddress一样去动态获取方法的地址。当然效率要根据复杂程度而决定,一般稍微复杂的处理性能损失可能超过20%,对于一些复杂的涉及Java自动类型转换判断,执行时间可能是直接引用的上千倍,所以最终我们调试时必须考虑性能问题。

*因为反射是动态的,所以需要处理很多异常,不然Dalvik崩溃出Force Close的概率会大很多,很简单的一个反射就需要至少3个异常捕获,本身try-catch效率就不是很高,自然进一步影响运行效率,对于Android开发我们必须考虑这些问题。

*反射因为导致代码臃肿,自然稍微复杂的几个方法实用反射将会导致代码可读性和维护性降低,如果很抽象的调用Android开发强烈不推荐这种方法。

3、反射的实际应用

 private void getTestData(){


        try {
            StorageManager storageManager =(StorageManager)getSystemService(Context.STORAGE_SERVICE);

            Class<?> aClass = Class.forName("android.os.storage.StorageManager");

            Method method = aClass.getMethod("getVolumes");
            method.setAccessible(true);

            if (method!=null){
                tv_test.setText(" "+method.invoke(storageManager));
                Log.e("MainActivity","method="+method.invoke(storageManager));
            }

        } catch (Exception e) {

            e.printStackTrace();
        }

    }
class.forName是包名加和类名,就是你需要获取的类的的包名+类名

getMethod里面是是要获取的方法名称

最后通过invoke就可以调用了

执行后打印的数据:

07-06 22:31:03.882 24208-24208/com.example.apple.reflection E/MainActivity: method=[VolumeInfo{private}:
                                                                                type=PRIVATE diskId=null partGuid=null mountFlags=0 mountUserId=-1 
                                                                                state=MOUNTED 
                                                                                fsType=null fsUuid=null fsLabel=null 
                                                                                path=/data internalPath=null 
                                                                            , VolumeInfo{emulated}:
                                                                                type=EMULATED diskId=null partGuid=null mountFlags=PRIMARY|VISIBLE 
                                                                                mountUserId=-1 state=MOUNTED 
                                                                                fsType=null fsUuid=null fsLabel=null 
                                                                                path=/storage/emulated internalPath=/data/media 
                                                                            ]

4、除了上面的还可以获取对象的所有属性

  // 获得对象的所有属性
            Field fields[] = aClass.getDeclaredFields();

            for (int i=0;i<fields.length;i++){
                Field field = fields[i];

                String fieldName = field.getName();
                String firstLetter = fieldName.substring(0, 1).toUpperCase();
                // 获得和属性对应的getXXX()方法的名字
                String getMethodName = "get" + firstLetter + fieldName.substring(1);
                // 获得和属性对应的setXXX()方法的名字
                String setMethodName = "set" + firstLetter + fieldName.substring(1);

                // 获得和属性对应的getXXX()方法
              //  Method getMethod = aClass.getMethod(getMethodName, new Class[] {});
                // 获得和属性对应的setXXX()方法
               // Method setMethod = aClass.getMethod(setMethodName, new Class[] { field.getType() });

                // 调用原对象的getXXX()方法
               // Object value = getMethod.invoke(new Object[] {});
              //  System.out.println(fieldName + ":" + value);
                // 调用拷贝对象的setXXX()方法
              //  setMethod.invoke(aClass, new Object[] { value });

                Log.e("MainActivity","fieldName="+fieldName+ " firstLetter="+firstLetter+
                " getMethodName="+getMethodName);
5、获取对象的类型

                //获得对象的类型:
                Class classType = aClass.getClass();
//                getName():获得类的完整名字;
//                getFields():获得类的public类型的属性;
//                getDeclaredFields():获得类的所有属性;
//                getMethods():获得类的public类型的方法;
//                getDeclaredMethods():获得类的所有方法;

                Log.e("MainActivity","classType="+classType.getName());
最后可亲自打印上面的数据来看。





  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值