What exactly does Android’s @hide annotation do?

What exactly does this do?

It controls what is in the android.jar that you are compiling against.

When you have, say, compileSdkVersion 19 in your build.gradle file, what is really happening is that $ANDROID_SDK/platforms/android-19/android.jar is being added to your compile-time classpath.

That JAR is created as part of compiling Android itself. The Android framework classes are analyzed, and a copy of them is created. This copy:

  • Strips out all classes, methods, fields, etc. marked with @hide

  • Has stub implementations of all the methods that remain (literally throw new RuntimeException("Stub!"), the last time I looked)

  • Retains the JavaDoc comments for everything that remains

The JavaDocs are built off of this source tree (which is why the JavaDocs do not show hidden methods), and the SDK edition of the framework JAR is compiled off of this source tree.

but that you can use reflection to access them

That is because, at runtime, the real framework JAR is in your runtime classpath, compiled off of the real source for the framework classes. It contains everything that was marked with @hide and was stripped out of the compile-time framework 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

As Karakuri noted, that sure looks like a compile error to me. If I try your code in a compileSdkVersion 22 project, I get a compile error. And when I go to run it, I get:

/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

Now, you can compile against methods that were formerly marked with @hide, because they were un-hidden in a later Android SDK, and your compileSdkVersion is on that API level or higher. Using those methods on API levels prior to when they were officially added to the SDK is risky.

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

You should, unless you are building only for one device where you control the firmware, including all OS updates. And, in that case, you are probably building your own firmware, and so you can build your own SDK framework JAR from your Android fork, where you remove @hide from the things you want to really use.

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

Based on what I see from your screenshot and my PC, that is a compile error from the IDE. You cannot disable compile errors.

Leave a Comment