java反射机制用途_Java反射机制(2)--反射的用途举例

前一篇文章介绍了反射功能的基本介绍。

今天写这篇文章是为了依据笔者项目的经验,讲讲反射在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版本,使用了不同的方法。 以上,欢迎大家留言补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值