@RequiresApi() and @ChecksSdkIntAtLeast() Annotations
@RequiresApi() and @ChecksSdkIntAtLeast() Annotations are used by lint tool in Android Studio to provide proper warning/error messages
One of the things I am confused about in Android development is these lint tool annotations. These annotations do not sound like lint tool annotations to me, but they are.
So, I call them lint tool annotations because it makes them clear to me on their purposes which provides you with the proper lint warning/error messages to you in Android Studio.
@RequiresAPI()
Let’s say you have a function that calls an Android API that requires min SDK 23, anything below 23 won’t work. You annotate @RequiresAPI(23)
in your function to let the caller knows that it won't work if the Android device is running below SDK 23.
@RequiresApi(23)
fun callFunctionThatRequiresAPI23() {
/* code here only applicable for SDK API 23 and above */
}
So, you call it from another function.
fun callerFunction(){
callFunctionThatRequiresAPI23()
}
You will get this lint error if you’re running on minSdk below 23. This error message is coming from the @RequiresApi(23)
annotation that I have in the previous function.
Call requires API level 23 (current min is 21): callFunctionThatRequiresAPI23
If you’re on minSdk 23, you won’t get this error message, and this makes sense because SDK 23 has no problem running the code. Please note that there isn’t any build error here, it is a lint error.
Based on the suggested fix, you annotate the function with @RequiresApi(23)
to get rid of the error message.
@RequiresApi(23)
fun callerFunction(){
callFunctionThatRequiresAPI23()
}
Well, this is wrong! You shouldn’t do this because calling this function on a device that running below 23 won’t work. It defeats the original purpose of the error message.
Instead, you should implement the code for SDK < 23. Without the need to add @RequiresApi(23)
, the error message goes away too if the following conditional check.
fun callerFunction(){
if (Build.VERSION.SDK_INT >= 23) {
callFunctionThatRequiresAPI23()
} else {
// implement code for SDK < 23
}
}
@ChecksSdkIntAtLeast()
If you extract out Build.VERSION.SDK_INT >= 23
to a function,
fun checkSDK23Version():Boolean = Build.VERSION.SDK_INT >= 23
and call it in the callerFunction(),
fun callerFunction(){
if(checkSDK23Version()) {
callFunctionThatRequiresAPI23()
} else {
// implement code for SDK < 23
}
}
nothing happens. The lint tool is smart enough to figure out the checkSDK23Version()
is indeed checking for minimum SDK 23 version.
Let’s modify checkSDK23Version()
to be slightly not straightforward.
fun checkSDK23Version(): Boolean {
Log.d("vtsen", "do something here")
return Build.VERSION.SDK_INT >= 23
}
The lint tool in Android Studio now complains of the same error message again.
Call requires API level 23 (current min is 21): callFunctionThatRequiresAPI23
In this scenario, you annotate the function with @ChecksSdkIntAtLeast(23)
to tell the lint tool that this checkSDK23Version()
is indeed checking for the SDK version.
@ChecksSdkIntAtLeast(23)
fun checkSDK23Version():Boolean {
Log.d("vtsen", "do something here")
return Build.VERSION.SDK_INT >= 23
}
The error message is now gone!
Summary
As a best practice, don’t simply add @RequiresAPI()
to get rid of the lint warnings/errors. Instead, add the conditional logic to handle the unsupported SDK version. On the hand, you can safely add @ChecksSdkIntAtLeast()
to get rid of the lint errors.
If you don’t like to hard code the build version code, you can check this BuiltUtils Android library out. It is nothing fancy here and probably missing some checks that you need. If so, feel free to contribute. This is a very beginner-friendly Android library for contribution anyway.
Originally published at https://vtsen.hashnode.dev.