今天在公司一个同事突然问我一个关于android提供的SDK源码中public对应的field无法访问的问题,我仔细的检查了一下相关的代码,没有发现代码有任何的问题,但是在调用该class对应的filed的时候却始终都报错,源码如下:
public static final class Email implements DataColumnsWithJoins, CommonColumns
/**
* The email address.
* <P>Type: TEXT</P>
* @hide TODO: Unhide in a separate CL
*/
public static final String ADDRESS = DATA1;
从以上代码可以看到Email这个类中有一个public的static field叫做ADDRESS,但是根据Email.ADDRESS访问一直提示找不到field。这个现象让我觉得非常的好奇,仔细的google了一下,发现原因就在于@hide这个annotation上面。
在android的SDK中有两类的API是无法直接访问的,一类是com.android.internal包下面的类,可以称之为internal API。另外一类就是通过hide这个annotation所标注的class,method或者field,可以称作hide api。(可惜没有在SDK中找到关于hide这个annotation的源码)
根据网上的信息,把internal封装的源码和通过hide annotation标注的代码进行一个小小的对比,原文来自http://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/
Hidden API之所以被隐藏,是想阻止开发者使用SDK中那些未完成或不稳定的部分(接口或架构)。举个例子,Bluetooth API在API 5(Android 2.0)上才开放;在API 3 和4上都是用@hide属性隐藏了。当这些API被验证和清理后,Google的开发者会移除@hide属性,并让其在API 5官方化。很多地方在API 4 和5之间发生了变化。如果你的程序依赖某些隐藏的API,当其部署到新的平台上时,就有可能陷入困境。
对于internal API来说,从来都没有计划将其开放出来。它就是Android的“内部厨房”,对开发者来说,应该将其视作黑盒。凡事都会有变化的。如果你依赖某些internal API,也有可能在新的Android release上,这些internal API发生变化,从而令你失望。
总结一下区别:
Hidden API = 进行中的工作;
Internal API = 黑盒;
一般情况下面,无论是hide api还是internal api都不能也不应该去访问,当然你可以通过java的反射机制绕过这层限制,同时原文中也介绍了一些不通过反射也同样可以访问这些api的小技巧。