Android的@hide注释究竟做了什么?

时间:2015-08-09 19:48:52

标签: java android hide lint

Android中的许多内部API都标记为@hide完全这是做什么用的?

Another answer说它只隐藏了Javadoc中的方法,但你可以使用反射来访问它们。

这没有任何意义 - 如果它们只是从Javadoc中隐藏,那么你肯定不需要反射来访问它们。事实上,我发现我没有。我仍然可以调用一些@hide方法(也许只是静态的方法?),应用程序编译并运行正常,据我所知。我只是得到一个lint错误:

Cannot resolve method

请注意,上面的代码仍然可以正常编译。

我不关心API被更改的可能性,所以我很高兴使用私有API,但有人可以解释这种行为吗?此外,如果有任何方法可以根据具体情况禁用lint,这将是有帮助的。

2 个答案:

答案 0 :(得分:19)

  

这到底是做什么的?

它控制您正在编译的android.jar中的内容。

如果在compileSdkVersion 19文件中有build.gradle,那么实际发生的事情是$ANDROID_SDK/platforms/android-19/android.jar被添加到编译时类路径中。

JAR是作为编译Android本身的一部分而创建的。分析Android框架类,并创建它们的副本。这份副本:

  • 删除标有@hide

  • 的所有类别,方法,字段等
  • 是否保留了所有剩余方法的存根实现(字面意思throw new RuntimeException("Stub!"),我上次看的时候)

  • 保留JavaDoc评论以保留所有剩余的内容

JavaDocs是基于这个源代码树构建的(这就是JavaDocs不显示隐藏方法的原因),框架JAR的SDK版本是从这个源代码树编译而来的。

  

但您可以使用反射来访问它们

这是因为,在运行时真正的框架JAR位于运行时类路径中,从框架类的真实源代码编译而来。它包含标有@hide的所有内容,并且已从编译时框架JAR中删除。

  

我仍然可以调用一些@hide方法(也许只是静态方法?),应用程序编译并运行正常,据我所知。我只是得到一个lint错误

正如Karakuri所说,这对我来说肯定是一个编译错误。如果我在compileSdkVersion 22项目中尝试您的代码,我会收到编译错误。当我去运行它时,我得到:

/tmp/MyApplication/app/src/main/java/com/commonsware/myapplication/MainActivity.java
Error:(16, 23) error: cannot find symbol method isEmailAddress(String)
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
Information:BUILD FAILED

现在,您可以针对以前标有@hide的方法进行编译,因为它们在以后的Android SDK中未被隐藏,而您的compileSdkVersion就是API级别或更高级别。在正式添加到SDK之前,在API级别上使用这些方法是有风险的。

  

我不关心API被更改的可能性

除非您仅为一个控制固件的设备(包括所有操作系统更新)构建,否则您应该这样做。而且,在这种情况下,您可能正在构建自己的固件,因此您可以从Android分支构建自己的SDK框架JAR,从中删除@hide您想要真正使用的东西。

  

此外,如果有任何方法可以根据具体情况禁用lint,这将有所帮助。

根据我从屏幕截图和我的电脑中看到的内容,这是来自IDE的编译错误。您无法禁用编译错误。

答案 1 :(得分:3)

谷歌使用@hide注释来删除他们不希望成为公共SDK的一部分的类和方法,因为他编译了你下载并用来编译代码的android框架jar。 (我不知道它是如何工作的具体细节,所以不要问。)这就是为什么你的IDE无法编译代码的原因 - 它们确实不存在。但是,实际设备上的android框架jar包含这些类和方法,这就是为什么可以在运行时使用反射访问它们。

您在帖子中显示的内容不是lint错误,即编译错误。它无法解析方法,这意味着它认为它不是有效的方法调用。