RequiresApi与TargetApi Android注解的区别

116

RequiresApiTargetApi有什么区别?

Kotlin示例:

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

注意: FingerprintManager.AuthenticationCallback 需要 API 级别为 M

注意2:如果我不使用 TargetApi lint,则会出现错误 该类需要 API 级别 23 ...

5个回答

100

@RequiresApi - 该注解表示被标记的元素仅可在给定的API级别或更高版本上调用。

@TargetApi - 该注解表示 Lint 应将此类型视为针对特定 API 级别,而不管项目的目标是什么。


67

首先,我会假设您的最小API版本低于您要调用的API版本,因为这是这种注释有意义的地方。

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

当一个方法被标注为这个时,每次调用该方法时,您会收到一个漂亮的红色警告,提示 这个调用需要比您的最低API版本更高的API版本,但这并不会阻止您编译和构建您的APK,它只会在较低版本的安卓上崩溃,我已经测试过了。

@TargetApi

这并没有什么帮助,它只是抑制了在您的方法中调用新 API 时出现的警告,但当您从其他地方调用此方法时,根本没有 Lint 警告,您仍然可以构建和安装您的 APK,只有当该方法被调用时才会导致崩溃。


8
我发现这篇回答比页面上其他回答更全面易懂,因此点赞。 - Anand Kumar Jha
3
这是唯一一个解释理论和实践的答案,它确实应该被接受。 - Dmitriy Pavlukhin
@RequiresApi 在低版本上会崩溃吗?我认为在此注释下,一个方法只能在给定的 API 级别或更高级别上调用。 - Bitwise DEVS
1
@BitwiseDEVS 是的,它“应该”在给定的API级别或更高级别上调用,但是如果您在不检查设备API级别的情况下调用该方法,则代码仍然会编译。我猜这是因为我们正在针对“compileSdkVersion”进行编译。当在较低的API级别设备上运行时,它将崩溃,因为旧版本的Android中没有这样的API。 - ssynhtn
@ssynhtn 这真是一个决定性的注释。另一个大问题是当它被应用于覆盖方法时。 - Bitwise DEVS

38

与Mike所说的类似,如您在文档中所见:

表示注解元素仅应在指定的API级别或更高级别上调用。

这与早期的@TargetApi注解目的相似,但更清楚地表达了这是对调用者的要求,而不是仅用于“抑制”方法中超出minSdkVersion的警告。

正如您在此处看到的,实际上是强制调用方验证在调用该方法时所使用的API,而不仅仅是从您的IDE/LINT中删除警告。

您可以将其与@NonNull或@Null注释进行比较,它们强制调用者可以/不能向函数发送null值。


21

以下是来自https://developer.android.com/reference/android/support/annotation/RequiresApi.html的JavaDocs:

[@RequiresApi] 这与旧的@TargetApi注释具有相似的目的,但更清晰地表达了这是对调用方的要求,而不是用于“抑制”超过minSdkVersion的方法内警告。

我想它们在功能上是等效的,但@RequiresApi似乎更新,并且有更高的机会扩展包括更多的功能。


@Penn 请解释一下这为什么是错误的吗? - hamena314

6

这两个都是用于处理添加到新的Android API级别而不影响其他API级别的功能。

RequiresApi

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

在这里,它表示注释的元素只应在给定的API级别或更高级别上调用。在给定API级别以下的注释元素将不会被调用。
目标API
@TargetApi(Build.VERSION_CODES.*api_code*)

表示 Lint 应将此类型视为针对特定 API 级别,而不管项目目标是什么。仅适用于指定的 API 级别。在其他 API 级别上不会被调用。


当我使用@RequiresApi时,AS用红色下划线标记了一个方法调用以及整个类作为包含错误。 - CoolMind
@CoolMind,你在任何方法中使用了“@RequiresApi”吗? - callmejeevan
不,我是在方法前添加的,就像 @TargetApi 一样。 - CoolMind
@CoolMind 尝试在你调用的方法中使用 "@RequiresApi"。或者像这样包围调用。 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.api_code) { // 你的方法名 } - callmejeevan
是的,if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 可以工作,但我已经在方法中使用了它。谢谢! - CoolMind
应该有一个选项来针对低于API的版本。这样,拥有需要不同API值的2种方法将不会在重新构建项目后在构建选项卡中显示任何警告消息。 - chitgoks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接