RequiereApi vs TargetApi anotaciones de Android

98

¿Cuál es la diferencia entre RequiresApiy TargetApi?

Muestra en kotlin:

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

NOTA: FingerprintManager.AuthenticationCallbackrequiere apiM

NOTA 2: si no uso TargetApi lint fallará con error class requires api level 23...

Daniel Gómez Rico
fuente

Respuestas:

87

@RequiresApi - Indica que el elemento anotado solo debe invocarse en el nivel de API dado o superior.

@TargetApi - Indica que Lint debe tratar este tipo como un objetivo de un nivel de API determinado, sin importar cuál sea el objetivo del proyecto.

Abhay
fuente
42

Primero asumiré que su versión de min api es más baja que la api a la que va a llamar, porque ahí es donde este tipo de anotaciones tienen sentido

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

Cuando se anota un método con esto, cada vez que llama a ese método, recibe una bonita advertencia roja de que esta llamada requiere una versión de la API que sea superior a su versión de la API mínima, pero no le impide compilar y construir su apk, simplemente fallará en versiones inferiores de Android cuando lo probé.

@TargetApi

Esto no ayuda en absoluto, suprime las advertencias de llamar a nuevas apis en su método, pero cuando llama a este método desde otro lugar, no hay ninguna advertencia de lint, y aún puede construir e instalar su apk solo para cumplir con un crash cuando se llama a ese método.

ssynhtn
fuente
2
Realmente lo encontré más completo y fácil de entender que las otras respuestas disponibles en esta página. Por lo tanto +1.
Anand Kumar Jha
1
Esta es la única respuesta que explica teoría + práctica, realmente debería aceptarse.
Dmitriy Pavlukhin
37

Similar a lo que dijo Mike, como puede ver en la documentación:

Indica que el elemento anotado solo debe invocarse en el nivel de API determinado o superior.

Esto es similar en propósito a la anotación @TargetApi anterior, pero expresa más claramente que esto es un requisito para la persona que llama, en lugar de usarse para "suprimir" advertencias dentro del método que exceden la minSdkVersion.

Como puede ver aquí, esto en realidad obliga a la persona que llama a verificar la API que se ha utilizado al llamar a este método, en lugar de simplemente eliminar la advertencia de su IDE / LINT.

Puede comparar esto con las anotaciones @NonNull o @Null, que imponen que la persona que llama puede / no puede enviar valores nulos a la función.

Jorge Aguilar
fuente
21

De los JavaDocs en https://developer.android.com/reference/android/support/annotation/RequiresApi.html :

[@RequiresApi] Esto es similar en propósito a la anotación @TargetApi anterior, pero expresa más claramente que esto es un requisito para la persona que llama, en lugar de usarse para "suprimir" advertencias dentro del método que exceden la minSdkVersion.

Supongo que son funcionalmente equivalentes, pero @RequiresApiparecen ser más nuevos y tienen una mayor probabilidad de ampliarse para incluir más funciones.

Mike Laren
fuente
@Penn Care para explicar por qué esto es falso?
hamena314
6

Ambos son para funciones de manejo agregadas a los nuevos niveles de API de Android sin afectar los otros niveles de API.

RequiereApi

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

Aquí dice que el elemento anotado solo debe invocarse en el nivel de API dado o superior. El elemento anotado debajo del nivel de API dado no llamará.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Indica que Lint debe tratar este tipo como dirigido a un nivel de API determinado, sin importar cuál sea el objetivo del proyecto. Solo destinado al nivel de API especificado. No se llamará en otro nivel de API.

jeevan venugopal
fuente
Cuando utilicé @RequiresApi, AS subrayó una llamada de método con rojo y también una clase completa que contenía un error.
CoolMind
@CoolMind, ¿usaste "@RequiresApi" dentro de algún método?
jeevan venugopal
No, lo agregué antes de un método, como @TargetApi.
CoolMind
@CoolMind intenta usar "@RequiresApi" para el método desde el que estás llamando. O rodee la llamada así. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES. * api_code *) {// nombre de su método}
jeevan venugopal
Sí, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {funciona, pero ya lo tengo en el método. ¡Gracias!
CoolMind