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 的编译错误。您不能禁用编译错误。
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 的编译错误。您不能禁用编译错误。