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

2022-09-03 18:01:14

Android中的许多内部API都标记了。这到底是做什么的?@hide

另一个答案说,它只对Javadoc隐藏了这些方法,但你可以使用反射来访问它们。

但是,这毫无意义 - 如果它们仅对Javadoc隐藏,那么您肯定不需要反射即可访问它们。事实上,我发现我没有。我仍然可以调用一些方法(也许只是静态方法?),并且据我所知,应用程序编译并运行良好。我只是得到一个棉绒错误:@hide

Cannot resolve method

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

我不在乎API被更改的可能性,所以我很高兴使用私有API,但是有人可以解释这种行为吗?此外,如果有任何方法可以逐案禁用lint,那将很有帮助。


答案 1

这到底是做什么的?

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

例如,当你的文件中有,真正发生的事情是将其添加到编译时类路径中。compileSdkVersion 19build.gradle$ANDROID_SDK/platforms/android-19/android.jar

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

  • 去掉所有标有@hide

  • 具有所有剩余方法的存根实现(从字面上看,我上次查看时)throw new RuntimeException("Stub!")

  • 保留所有剩余内容的 JavaDoc 注释

JavaDocs 是基于此源代码树构建的(这就是为什么 JavaDocs 不显示隐藏方法的原因),而框架 JAR 的 SDK 版本就是根据此源代码树编译的。

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

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

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

正如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

现在,您可以针对以前标记为 的方法进行编译,因为它们在后来的 Android SDK 中未隐藏,并且您处于该 API 级别或更高级别。在正式将这些方法添加到 SDK 之前,在 API 级别使用这些方法是有风险的。@hidecompileSdkVersion

我不在乎API被更改的可能性

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

此外,如果有任何方法可以逐案禁用lint,那将很有帮助。

根据我从您的屏幕截图和我的PC中看到的内容,这是IDE的编译错误。不能禁用编译错误。


答案 2

不知何故,Google使用注释从您下载并用于编译代码的已编译Android框架jar中剥离出他们不希望成为公共SDK一部分的类和方法。(我不知道它是如何工作的,所以不要问。这就是为什么你的IDE不能针对它们编译你的代码的原因 - 它们实际上并不存在。但是,实际设备上的android框架jar确实包含这些类和方法,这就是为什么可以使用反射在运行时访问它们的原因。@hide

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


推荐