Android中巧用Java反射机制 :兼容新老版本的SDK、使用私有的API
2013-07-13 15:39
411 查看
在Android中,可以从下面两点考虑来使用Java反射(Java Reflection)机制,从而达到意想不到的效果。这里也将展示Google是怎样在自己的应用中来使用Java反射机制的。
1. 同时兼容新老版本的SDK
Android往往会在新版本中引入一些新的API来替代老的API,这些新的API在性能或者易用性上比老的API更好。但为了兼容性,新老API往往是共存的。
在这种情况下,你的应用如果调用了新的API,是没办法在安装老版本Android的设备上运行的,但如果使用老的API,又没办法在安装新版本Android的设备上体现新API的性能。
这时候,就可以使用Java反射机制,从而实现一个apk,如果安装在老版本Android的设备上,则调用老的API;安装在新版本Android的设备上,则调用新的API。
下面是来自Google的一段代码:
public class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
private static Method findApplyMethod() {
try {
return SharedPreferences.Editor.class.getMethod("apply", new Class[0]);
} catch (NoSuchMethodException e) {
return null;
}
}
public static void apply(SharedPreferences.Editor editor) {
if (sApplyMethod != null) {
try {
sApplyMethod.invoke(editor, new Object[0]);
return;
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
editor.commit();
}
}
2. 使用私有的API
如果在Eclipse上开发应用,必须调用对应的Android SDK的标准API,即在开发文档中说明的API。调用非标准的即私有的API,是编译不过的。
但Android实际上有很多API,是被@hide标注的。被@hide注解的类和方法就是私有API。如果一个应用想调用这些API,则只有在编译整个系统image的时候才能编译过,而在Eclipse上是编译不过的。所以,这些API往往会被手机开发商的本地应用调用,则第三方的应用是没办法调用的。
这种情况下,可以使用Java反射机制来调用这些私有的API。一旦编译通过生成了apk,就能正常在手机上运行,因为这样的API的实现已经在手机系统中只是没有公开出来。
下面是来自Google的一段代码:
private static final String AMR_INPUT_STREAM_CLASS = "android.media.AmrInputStream";
private static Class<?> getAmrInputStreamClass() throws ClassNotFoundException {
return Class.forName(AMR_INPUT_STREAM_CLASS);
}
private static InputStream createAmrInputStream(InputStream in) {
try {
Class<?> clazz = getAmrInputStreamClass();
Constructor<?> constructor = clazz.getConstructor(new Class[] { InputStream.class });
return (InputStream)constructor.newInstance(new Object[] { in });
}
...
}
1. 同时兼容新老版本的SDK
Android往往会在新版本中引入一些新的API来替代老的API,这些新的API在性能或者易用性上比老的API更好。但为了兼容性,新老API往往是共存的。
在这种情况下,你的应用如果调用了新的API,是没办法在安装老版本Android的设备上运行的,但如果使用老的API,又没办法在安装新版本Android的设备上体现新API的性能。
这时候,就可以使用Java反射机制,从而实现一个apk,如果安装在老版本Android的设备上,则调用老的API;安装在新版本Android的设备上,则调用新的API。
下面是来自Google的一段代码:
public class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
private static Method findApplyMethod() {
try {
return SharedPreferences.Editor.class.getMethod("apply", new Class[0]);
} catch (NoSuchMethodException e) {
return null;
}
}
public static void apply(SharedPreferences.Editor editor) {
if (sApplyMethod != null) {
try {
sApplyMethod.invoke(editor, new Object[0]);
return;
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
editor.commit();
}
}
2. 使用私有的API
如果在Eclipse上开发应用,必须调用对应的Android SDK的标准API,即在开发文档中说明的API。调用非标准的即私有的API,是编译不过的。
但Android实际上有很多API,是被@hide标注的。被@hide注解的类和方法就是私有API。如果一个应用想调用这些API,则只有在编译整个系统image的时候才能编译过,而在Eclipse上是编译不过的。所以,这些API往往会被手机开发商的本地应用调用,则第三方的应用是没办法调用的。
这种情况下,可以使用Java反射机制来调用这些私有的API。一旦编译通过生成了apk,就能正常在手机上运行,因为这样的API的实现已经在手机系统中只是没有公开出来。
下面是来自Google的一段代码:
private static final String AMR_INPUT_STREAM_CLASS = "android.media.AmrInputStream";
private static Class<?> getAmrInputStreamClass() throws ClassNotFoundException {
return Class.forName(AMR_INPUT_STREAM_CLASS);
}
private static InputStream createAmrInputStream(InputStream in) {
try {
Class<?> clazz = getAmrInputStreamClass();
Constructor<?> constructor = clazz.getConstructor(new Class[] { InputStream.class });
return (InputStream)constructor.newInstance(new Object[] { in });
}
...
}
相关文章推荐
- android-support-vXXX.jar 支持包(老版本使用新API) (部分新API做成第三方包) 向前兼容,低版本跑新API (提供低版本没有的新API)
- 我的Android进阶之旅------>Android中高低API版本兼容使用@TargetApi或者@SuppressLint("NewApi")
- 使用 Build.VERSION.SDK_INT兼容不同版本的API
- 【android】两类不能在SDK中使用的API------@hide和internal API介绍
- Android使用DownloadMange进行版本更新(兼容7.0)
- 关于sdk更新Android SDK Tools 25.3.1版本后使用sdk manager闪退
- 使用Android lint发现并解决高版本API问题
- android 在使用ViewAnimationUtils.createCircularReveal()无法兼容低版本的情况下,另行实现圆形scale动画
- 【微信分享】 微信分享集成 使用weixin js sdk 兼容 旧版本 2
- Android SDK Manager无法下载其他版本的API 解决办法
- android 6.0(api 23) SDK以上版本 org.apache.http.*不支持解决办法
- 怎样在xcode5中使用低版本sdk,解决兼容ios7ui问题
- 安卓开发中,在低版本SDK使用高版本的API会报错。一般处理方法是换一种实现方法,或者在高版本SDK中使用高版本API,低版本SDK中使用效果可能会差点的折衷方案;后者可以用如下技巧来实现。
- [Android]高低API版本兼容之@TargetApi
- 一分钟解决Android 安卓 API版本兼容
- 使用Android lint发现并解决高版本API问题
- 4.Android与JS的交互(兼容API 17以下版本)
- Android.mk里添加 LOCAL_SDK_VERSION := current 后不能使用@hide API
- Android API Level与sdk版本对照表