Android开发中,时常要去查看源码,我们会发现源码里面有些方法是加上了 @hide ,或者 {@hide} 注解的,就像下面这 2 个方法。
(代码截取自:android.os.storage.StorageManager.java)
那么这两个注解有什么用处呢?
在说这两个注解标记之前,首先我们要知道 java 里面 /** xxx */ 表示javadoc(文档)注释。
当你在方法、类名、或者变量上加上这样的文档注释之后,别的地方引用到这些被你添加了文档注释的方法、类、变量时,就能很方便的看到原作者(也就是你)留下的注释信息,这将会有利于别人理解你的想法或者思路。当然居然是文档注释,那么通过javadoc生成文档时,这些注释信息也就会被输出来。比如我们创建如下方法,并加上适当的文档注释信息:
当我们调用这个方法时,我们添加的文档注释信息就会显示出来了。
切记:一定要是 /** */,只有它才表示 文档注释,只有文档注释的信息才会在调用出显示,或者随javadoc输出。 /* */ 只表示普通的多行注释,注释信息是不能显示或者输出的! 单行注释 // 就更不用说了,绝对出不来的!
这里我们就不掩饰 javadoc 输出的文档信息了。(PS:实际上是博主没用过,还不知道怎么用,有兴趣的可以自己查查资料)
当我们知道什么是文档注释之后,接下来就可以说说 @hide ,{@hide} 注解了。(百度百科那边有个解释,有兴趣的可以看看)
在源码中,类或API是否开放,是通过doc的注释{@hide}来控制的。方法、类、变量前面加上 {@hide} 注解之后,这个被注解的对象将会在生成 android.jar 的时候被刻意屏蔽掉,也就是SDK不可见的,这样就使得使用 android.jar 的开发者不能直接调用这些被注解的对象,但一旦APP编译好,安装到机器上之后,APP调用的就不是SDK里面的 android.jar 了,所以还是可以通过反射调用那些被添加 {@hide} 的对象的。被添加的这俩注解的对象,是 Google 不想被广大开发者访问到,可是出于 API 不稳定,或者兼容性不强考虑的,后期一旦稳定性或者兼容性得到验证,就会被开放出来了。
而 @hide 注解呢?它和 {@hide} 又有什么区别呢?
实际情况就是这两种注解的效果没什么区别,都一样能让被注解的对象成为 SDK不可见 的。至于它俩有啥区别,博主查了很多资料,也问了一些同事、大神,他们一致说没区别,只不过一个是标准的写法,一个是不怎么严谨的写法。至于哪个是便准的,哪个是不严谨的,个人持有疑问,这里也就不写出来误导大家了。
因为这两个注解只能在源码里面才有效,我们自己写的不想公开的类、方法、变量等,加上这俩注解是没效果的,所以大家也就没必要深究它俩到底有啥区别了,只需要知道它俩差不多,都是让被注解的对象成为 SDK不可见 的,让开发者不能直接访问。
但是不想被访问,并不代表不能被访问!
上面说了源码里面有,但被添加了 @hide 或者 {@hide} 注解的对象,是Google不想被开发者访问到的,但这并不代表他们不能被访问。在真机或者模拟器的系统里面,那些被注解的对象是存在的,只有在生成 SDK 的时候才会被刻意屏蔽掉。我们在开发的APP最终是运行在真机上的,一旦APP部署到机器上了,那些被隐藏的对象也就是可以访问的了。
我们开发是基于SDK的,也就是说我们不能直接调用哪些被隐藏的对象,因为他们在 SDK 里面不存在,所以编译器会报错,无法进行编译,也就没法打包生成 APK 文件了。
怎么访问这些被隐藏的对象呢?
上面已经提到过一种方法,就是通过反射调用,这里博主就不进行掩饰了。(PS:实际是博主反射没学好,不会反)
这里我将介绍另外一种方法,也就是能直接访问这些被隐藏对象的方法,进而使的能编译通过。
以访问一开始提到的 android.os.storage.StorageManager.java 为例,这里这个类是 framework 里面的(别问我怎么知道的,经验而已)。我们开发中想调用下面的方法就会报错,进而不能通过编译,也就不能生成APK了。
废话不多说,下面就是见证奇迹的时刻:
1、搞到源码,编译了;
2、进入 out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\ 目录,将 classes.jar 复制项目 lib 下,并改名为 framework_orginal.jar (也可不改名);
3、选择项目属性->Java Build Path->Libraries->Add Library->User Library->Next-> UserLibraries进入到User Libraries管理界面,点击New新建一个User Library,比如android_framework_orginal,点击Add Jars把Jar包加入到建立的User Library中,然后选中刚建的User Library,确定。
4、此时我们回到工程会发现,问题并没有解决,依旧在报错。接着我们进行最关键的,也是比较容易忽略的一步操作。
选择项目属性->Java Build Path-> Order & Export,通过右侧的 “Up”,“Down”按钮,将我们添加进来的 android_framework_original 移动到项目原有的 Android xxx 上面,点击“Apply”,然后确定,回到工程,就OK啦。