Lots of internal APIs in Android are marked @hide
. What exactly does this do?
Another answer says that it only hides the methods from Javadoc, but that you can use reflection to access them.
That makes no sense though - if they are only hidden from Javadoc then you surely wouldn't need reflection to access them. In fact I've found that I don't. 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:
Note that the above code still compiles fine.
I don't care about the possibility of the API being changed so I am happy using the private API, but can someone explain this behaviour? Also if there's any way to disable the lint on a case-by-case basis that would be helpful.
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.
Somehow Google uses the @hide
annotation to strip out the classes and methods they don't want to be part of the public SDK fromt he compiled android framework jar that you download and use to compile your code against. (I don't know the specifics of how that works, so don't ask.) That's why your IDE cannot compile your code against them -- they literally don't exist. However, the android framework jar on an actual device DOES contain these classes and methods, which is why they can be accessed at runtime using reflection.
What you displayed in your post is not a lint error, that is a compile error. It cannot resolve the method, meaning it thinks it's not a valid method call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With