Android中巧用Java反射机制
在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 }); } ... }