113

Whats the difference between RequiresApi and TargetApi?

Sample in kotlin:

@RequiresApi(api = Build.VERSION_CODES.M)
@TargetApi(Build.VERSION_CODES.M)
class FingerprintHandlerM() : FingerprintManager.AuthenticationCallback()

NOTE: FingerprintManager.AuthenticationCallback requires api M

NOTE 2: if I dont use TargetApi lint fail with error class requires api level 23...

Daniel Gomez Rico
  • 15,026
  • 20
  • 92
  • 162

5 Answers5

99

@RequiresApi - Denotes that the annotated element should only be called on the given API level or higher.

@TargetApi - Indicates that Lint should treat this type as targeting a given API level, no matter what the project target is.

Abhay
  • 3,151
  • 1
  • 19
  • 29
66

I'll first assume your min api version is lower than the api you are going to call, because that's where these kind of annotations make any sense

@RequiresApi(Build.VERSION_CODES.N_MR1)
public void hello() { // codes that call system apis introduced in android N_MR1}

When a method is annotated with this, anytime you call that method, your receive a nice red warning that this call requires api version that is higher than your min api version, but it doesn't stop you from compiling and building your apk, it will just crash on lower versions of android as I tested it.

@TargetApi

This doesn't help at all, it suppress warnings of calling new apis in your method, but when you call this method from somewhere else, there is no lint warning at all, and you can still build and install your apk only to meet a crash when that method is called.

ssynhtn
  • 1,307
  • 12
  • 18
  • 8
    I really found it more comprehensive and easy to understand rather than the other answers available on this page. Hence +1. – Anand Kumar Jha Aug 11 '18 at 12:24
  • 3
    This is the only answer that explains theory+practice, it really should be accepted. – Dmitriy Pavlukhin Apr 25 '19 at 18:36
  • `@RequiresApi` will crash on lower version? I thought under this annotation a method should only be called on the given API level or higher. – Bitwise DEVS Jun 21 '21 at 05:21
  • 1
    @BitwiseDEVS yes it "should" be called on the given api level or higher, but if you call that method without checking the device api level, the code still compiles, I assume because we are compiling against "compileSdkVersion", when running on a lower api level device, it will crash because there is no such api in older versions of android – ssynhtn Jun 22 '21 at 08:06
  • @ssynhtn that is really a decisive annotation. another big problem is when this was applied in ovverriding a method. – Bitwise DEVS Jun 22 '21 at 09:00
38

Similar to what Mike said, as you can see in the documentation:

Denotes that the annotated element should only be called on the given API level or higher.

This is similar in purpose to the older @TargetApi annotation, but more clearly expresses that this is a requirement on the caller, rather than being used to "suppress" warnings within the method that exceed the minSdkVersion.

As you can see here, this is actually enforcing the caller to verify the API that's been used when calling into this method, instead of just removing the warning from your IDE/LINT.

You can compare this to the @NonNull or @Null annotations, they enforce that the caller can/can't send null values into the function.

Community
  • 1
  • 1
Jorge Aguilar
  • 3,442
  • 30
  • 34
21

From the JavaDocs in https://developer.android.com/reference/android/support/annotation/RequiresApi.html:

[@RequiresApi] This is similar in purpose to the older @TargetApi annotation, but more clearly expresses that this is a requirement on the caller, rather than being used to "suppress" warnings within the method that exceed the minSdkVersion.

I suppose they're functionally equivalent but @RequiresApi seems to be newer and has a higher chance of being extended to include more functionality.

Mike Laren
  • 8,028
  • 17
  • 51
  • 70
6

Both of them are for handling feature added to new android API levels without affecting the other API levels.

RequiresApi

@RequiresApi(api = Build.VERSION_CODES.*api_code*)

Here it says that the annotated element should only be called on the given API level or higher. The annotated element below the given API level won't call.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Indicates that Lint should treat this type as targeting a given API level, no matter what the project target is. Only meant for specified API level. Won't called on other API level.

callmejeevan
  • 1,040
  • 1
  • 9
  • 18
  • When I used `@RequiresApi`, AS underlined a method call with red and also a whole class as containing an error. – CoolMind Aug 27 '19 at 12:21
  • @CoolMind did you used "@RequiresApi" inside any method? – callmejeevan Aug 27 '19 at 12:31
  • No, I added it before a method, like `@TargetApi`. – CoolMind Aug 27 '19 at 12:32
  • @CoolMind try to use the "@RequiresApi" to the method you are calling from. Or surround the call like this. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.*api_code*) { // your method name } – callmejeevan Aug 27 '19 at 12:44
  • Yes, `if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {` works, but I already have it in the method. Thanks! – CoolMind Aug 27 '19 at 13:03
  • There should be an option to target apis below the api. That way, having 2 methods which requires different api values will not show any warning message in the build tab after rebuilding the project. – chitgoks Jan 14 '23 at 05:40