android 反射使用

来源:互联网 发布:mac os大小 编辑:程序博客网 时间:2024/06/06 06:35

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());
最后可亲自打印上面的数据来看。





原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 生孩子痔疮脱出不能回纳怎么办 痔疮犯了屁眼疼怎么办 孕晚期得痔疮了怎么办 孕39周痔疮严重怎么办 顺产后长痔疮了怎么办 怀孕了犯痔疮了怎么办 怀孕了痔疮犯了怎么办 痔疮手术后肛裂怎么办 痔疮引起的肛裂怎么办 痔疮手术后伤口不愈合怎么办 痔疮手术后伤口痒怎么办 肛瘘手术十五天后伤口疼怎么办 leep刀后hpv还是阳性怎么办 结肠息肉钳除后怎么办 痔疮手术后排便困难怎么办 住院未结账跑了怎么办 来月经痔疮犯了怎么办 安保压不下宫缩怎么办 肛周脓肿术后假性愈合怎么办 肛门的皱褶肿了怎么办 1月婴儿排便困难怎么办 吃完辣的痔疮肿了怎么办 肛裂怎么办兰州来医博.相信 胎儿脐带绕颈一周怎么办 郑大一附院怎么办合作医疗 痔疮包不消怎么办很疼 痔疮内扎手术后直肠窄小怎么办 2个月大的宝宝鼻塞怎么办 宝宝鼻屎比较深怎么办 来例假痔疮犯了怎么办 微医爽约过一次怎么办 炸完的薯条软了怎么办 学信网号码换了怎么办 学信网注册换手机了怎么办 学信网手机号码已被注册怎么办 学信网手机号码被注册了怎么办 去英国留学不会做饭怎么办 小米陶瓷刀钝了怎么办 橱柜的缝擦不到怎么办 悠悠球上油早了怎么办 买了没有esp的车怎么办