Android 的@hide 注释到底做了什么?

What exactly does Android's @hide annotation do?

Android 中的许多内部 API 标记为 @hide究竟是做什么的?

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

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

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

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

Google 以某种方式使用 @hide 注释去除了 类 和他们不想成为 public SDK 一部分的方法,他编译了 android 您下载并用于编译代码的框架 jar。 (我不知道它是如何工作的细节,所以不要问。)这就是为什么你的 IDE 不能针对它们编译你的代码——它们实际上不存在。但是,实际设备上的 android 框架 jar 确实包含这些 类 和方法,这就是为什么可以在运行时使用反射访问它们的原因。

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

What exactly does this do?

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

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

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

  • 去除所有类、方法、字段等标记为@hide

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

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

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

but that you can use reflection to access them

那是因为,在运行时间真实框架JAR在你的运行时间类路径,根据框架的真实源代码编译 类。它包含标有 @hide 并从编译时框架 JAR 中删除的所有内容。

I can still call some @hide methods (maybe just static ones?) and the app compiles and runs fine as far as I can tell. I just get a lint error

正如 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 级别上使用这些方法是有风险的。

I don't care about the possibility of the API being changed

你应该,除非你只为你控制固件的一台设备构建,包括所有 OS 更新。而且,在那种情况下,您可能正在构建自己的固件,因此您可以从 Android 分支构建自己的 SDK 框架 JAR,从中删除 @hide 您想要真正使用的东西。

Also if there's any way to disable the lint on a case-by-case basis that would be helpful.

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