Java反射机制(2)--反射的用途举例
2015-08-04 19:01
597 查看
前一篇文章介绍了反射功能的基本介绍。
今天写这篇文章是为了依据笔者项目的经验,讲讲反射在Android的三个具体用途。欢迎大家一起补充讨论。
获取系统编译后隐藏的方法,比如源码中使用
确认方法是否存在。这些方法有可能是自己自定义并添加的。笔者将以Android中的
兼容不用的Android版本,在Android系统的不断迭代中,有很多方法都是不断消失,不断出现的。需要我们对其做兼容处理。其实这也是第一种情况的引申。
不过虽然可以通过反射调用执行,但这个TelephonyMananger的这两个方法执行后是有权限问题的,感兴趣的朋友可以看看我的另一篇文章。
主App中通过反射获取此方法,代码如下:
如此,便可以方便的获取目标App的方法了。如果在代码中我们直接使用Activity实例,肯定是不能直接调用此方法的。如果对createPackageContext不熟悉的朋友,可以看下这篇文章。
其中apply方法是API9的时候拥有的,而commit()方法是API1拥有的。对此可以做如下处理:
在Editor的提交的过程中,我们依据API版本,使用了不同的方法。
以上,欢迎大家留言补充。
今天写这篇文章是为了依据笔者项目的经验,讲讲反射在Android的三个具体用途。欢迎大家一起补充讨论。
获取系统编译后隐藏的方法,比如源码中使用
/*hide*/修饰的函数。
确认方法是否存在。这些方法有可能是自己自定义并添加的。笔者将以Android中的
createPackageContext()(获取另外一个App的资源和方法)为例讲解。
兼容不用的Android版本,在Android系统的不断迭代中,有很多方法都是不断消失,不断出现的。需要我们对其做兼容处理。其实这也是第一种情况的引申。
第一种情况举例:
在Android5.0中,有个控制手机网络状态的类TelephonyMananger。它的setDataEnabled和getDataEnabled是隐藏的,但可以通过反射进行调用。public void setMobileDataState(Context cxt, boolean mobileDataEnabled) { TelephonyManager telephonyService = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE); try { Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class); if (null != setMobileDataEnabledMethod) { setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled); } } catch (Exception e) { LogHelper.v(TAG, "Error setting" + ((InvocationTargetException)e).getTargetException() + telephonyService); } } public boolean getMobileDataState(Context cxt) { TelephonyManager telephonyService = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE); try { Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled"); if (null != getMobileDataEnabledMethod) { boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService); return mobileDataEnabled; } } catch (Exception e) { LogHelper.v(TAG, "Error getting" + ((InvocationTargetException)e).getTargetException() + telephonyService); } return false; }
不过虽然可以通过反射调用执行,但这个TelephonyMananger的这两个方法执行后是有权限问题的,感兴趣的朋友可以看看我的另一篇文章。
第二种情况举例:
目标App中的Activity中声明getStr方法,返回一个字符串。确认安装。public static String getStr(){ return "String from TargetApp"; }
主App中通过反射获取此方法,代码如下:
try { mContext = createPackageContext("com.baidu.www.targetapp", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); Class mClass = mContext.getClassLoader().loadClass("com.baidu.www.targetapp.MainActivity"); Object target = mClass.newInstance(); Method method = mClass.getMethod("getStr"); Object obj = method.invoke(target); } catch (Exception e) { e.printStackTrace(); }
如此,便可以方便的获取目标App的方法了。如果在代码中我们直接使用Activity实例,肯定是不能直接调用此方法的。如果对createPackageContext不熟悉的朋友,可以看下这篇文章。
第三种情况举例:
在SharedPreferences.Editor中有个方法:public abstract void apply (); public abstract boolean commit ();
其中apply方法是API9的时候拥有的,而commit()方法是API1拥有的。对此可以做如下处理:
public class ShareActionClass { //反射 public static void setDataR(Context cxt, String str){ SharedPreferences sharedPreferences = cxt.getSharedPreferences("Test", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("strData", str); Method mMethod = null; if (Build.VERSION.SDK_INT > 9) { try { mMethod = editor.getClass().getDeclaredMethod("apply"); try { mMethod.invoke(editor); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } }else{ try { mMethod = editor.getClass().getDeclaredMethod("commit"); try { mMethod.invoke(editor); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } } public static String getDataR(Context cxt){ SharedPreferences sharedPreferences = cxt.getSharedPreferences("Test", Context.MODE_PRIVATE); Method method = null; try { method = sharedPreferences.getClass().getMethod("getString", new Class[]{String.class, String.class}); try { Object obj = method.invoke(sharedPreferences, "strData", ""); return (String)obj; } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } }
在Editor的提交的过程中,我们依据API版本,使用了不同的方法。
以上,欢迎大家留言补充。
相关文章推荐
- jdk1.5新特性之-------静态导入
- Java NIO原理 图文分析及代码实现
- java面向对象编程基础总结
- java题目练手
- JAVA学习第十四天
- java学习
- java数据类型
- javax.inject中@Inject、@Named、@Qualifier和@Provider用法
- JAVA 浮点数转化为百分数,分离整数和小数部分
- JAVA 浮点数转化为百分数,分离整数和小数部分 分类: Java 2015-08-04 18:11 10人阅读 评论(0) 收藏
- java杂笔
- 自动化打开并连接visual studio emulator for android,支持eclipse vs 以及as调试
- Java相等性测试
- Java实现文件复制
- 使用spring的aop进行权限拦截
- Maven+SpringMVC+MyBatis 上传图片
- 【Java并发编程实战】—–synchronized
- java字符串的hashCode
- springmvc运行机制
- Java基础---折半查找和进制转换