返回

Android注解详解:RequiresApi与TargetApi的差异

Android

RequiresApi 与 TargetApi:Android 注解差异

在Android开发中,RequiresApiTargetApi 这两个注解经常被用来处理不同Android API级别引入的新特性,特别是处理向下兼容的问题。两者用途相似,但其行为机制和影响范围截然不同。理解它们之间的差异,对于构建健壮的Android应用至关重要。

RequiresApi 注解

RequiresApi 注解用于标记某个方法、类、字段或者构造函数,这些元素依赖于某个特定API级别才能正常工作。当某个使用了 RequiresApi 注解的代码被调用,但应用运行的Android系统API级别低于指定值时,系统会产生运行时错误(或者lint错误)。这是一种保护机制,它可以避免应用在使用较低版本的Android设备上因调用不存在的API而崩溃。

import android.os.Build
import androidx.annotation.RequiresApi

class MyUtils {
  @RequiresApi(Build.VERSION_CODES.O)
  fun useNewFeature() : String{
       return  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             "Android O feature."
          } else {
             "Fallback code."
          }
  }

  fun someFunction() : String {
        // ... other function
         return useNewFeature(); //lint error in build
    }
}

上例中,useNewFeature() 依赖于 Android O (API 26) 及以上版本的功能。如果应用的运行环境低于API 26,IDE会报出一个lint错误,提示该方法使用了较高版本才能使用的API。需要注意的是, RequiresApi 注解的作用范围是整个方法,并不局限于方法内部调用新的api。这在安全性和规范方面是极佳的实践方式。

操作步骤:

  1. 仔细检查应用代码中需要使用特定 API 级别的代码块。
  2. 使用@RequiresApi 注解标记这些方法,指明所需的 API 级别。

TargetApi 注解

RequiresApi 不同,TargetApi 注解主要用于告诉lint工具,或者IDE,“此代码块设计在目标API版本或更高版本上运行,无需对此代码块内的低版本API兼容性进行lint检查”。换句话说, TargetApi 注解在运行时并不产生直接影响,它只是告知 lint 检查器:该部分代码已知并预期会在更高版本的 API 上运行。 这是一个让Lint忽略警告的方式。

import android.os.Build
import androidx.annotation.TargetApi

class MyClass {

  @TargetApi(Build.VERSION_CODES.M)
   fun myMethod(){
        //do sth for api 23+, this is OK if api < 23, do not show warning.
      }
}

在上面的示例中,myMethod 函数被标记为@TargetApi(Build.VERSION_CODES.M), 意味着当 Lint 工具检查这段代码时,即便其中有使用了 API 23 (Android 6.0) 或更高版本的新 API,也不会报告警告,Lint 将认为这是符合预期情况的。这种方法可以减少无意义的 Lint 警告。需要特别注意的是, TargetApi 并不会解决由于运行在较老设备上缺少新 API 而产生的运行时问题。

操作步骤:

  1. 分析确定可以安全地使用指定API级别特性的代码块。
  2. 使用 @TargetApi 注解标记这些代码块或方法,表明期望运行的目标API级别。

两者之间的根本区别

关键的区别在于 RequiresApi 会影响代码的运行时行为,强制运行时API的检查。如果API级别不满足条件,就应该避免使用这些特性。而 TargetApi 主要影响静态代码分析工具(Lint) 的行为。 它仅仅是告知工具:这个代码段已考虑到API的版本差异,不需要产生警告,主要为了让lint静默,并不检查该API实际版本。简单理解 RequiresApi是为用户运行时安全服务的; TargetApi 是为开发时的静态分析服务的。

安全开发建议

  • 尽可能在条件语句中使用API检查,并在if(Build.VERSION.SDK_INT >= yourSdkVersion) 代码块中使用新特性。这样即使在运行较旧API级别的设备上,也能保证应用不会崩溃,代码逻辑能够回退。
  • 正确使用 RequiresApi 注解可以提升代码可读性,使其他开发者能够更快理解该API版本的要求。
  • 不要滥用TargetApi,错误的使用可能会导致在低于指定API级别的设备上发生运行时异常,应用行为出现偏差,并降低程序质量。

理解 RequiresApiTargetApi 注解的不同及其使用场景,是编写高质量Android应用的关键一环。根据具体需求和环境合理应用这两种注解,能够使应用更好地适应不同的Android系统版本,并提供更安全可靠的用户体验。