Nécessite les annotations Android Api vs TargetApi

98

Quelle est la différence entre RequiresApiet TargetApi?

Échantillon à kotlin:

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

REMARQUE: FingerprintManager.AuthenticationCallbacknécessite une APIM

REMARQUE 2: si je n'utilise pas de charpie TargetApi, échoue avec une erreur class requires api level 23...

Daniel Gomez Rico
la source

Réponses:

87

@RequiresApi - Indique que l'élément annoté ne doit être appelé qu'au niveau d'API donné ou supérieur.

@TargetApi - Indique que Lint doit traiter ce type comme ciblant un niveau d'API donné, quelle que soit la cible du projet.

Abhay
la source
42

Je suppose d'abord que votre version d'API min est inférieure à l'API que vous allez appeler, car c'est là que ce type d'annotations a un sens

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

Lorsqu'une méthode est annotée avec ceci, chaque fois que vous appelez cette méthode, vous recevez un joli avertissement rouge indiquant que cet appel nécessite une version api supérieure à votre version min api, mais cela ne vous empêche pas de compiler et de construire votre apk, il va simplement planter sur les versions inférieures d'Android comme je l'ai testé.

@TargetApi

Cela n'aide pas du tout, cela supprime les avertissements d'appels de nouveaux apis dans votre méthode, mais lorsque vous appelez cette méthode ailleurs, il n'y a aucun avertissement de peluche, et vous pouvez toujours créer et installer votre apk uniquement pour rencontrer un planter lorsque cette méthode est appelée.

ssynhtn
la source
2
Je l'ai vraiment trouvé plus complet et plus facile à comprendre que les autres réponses disponibles sur cette page. D'où +1.
Anand Kumar Jha du
1
C'est la seule réponse qui explique la théorie + la pratique, elle devrait vraiment être acceptée.
Dmitriy Pavlukhin
37

Similaire à ce que Mike a dit, comme vous pouvez le voir dans la documentation:

Indique que l'élément annoté ne doit être appelé qu'au niveau d'API donné ou supérieur.

Cette fonction est similaire à celle de l'ancienne annotation @TargetApi, mais exprime plus clairement que c'est une exigence de l'appelant, plutôt que d'être utilisée pour "supprimer" les avertissements dans la méthode qui dépassent la minSdkVersion.

Comme vous pouvez le voir ici, cela oblige en fait l'appelant à vérifier l'API qui a été utilisée lors de l'appel de cette méthode, au lieu de simplement supprimer l'avertissement de votre IDE / LINT.

Vous pouvez comparer cela aux annotations @NonNull ou @Null, elles imposent que l'appelant puisse / ne puisse pas envoyer de valeurs nulles dans la fonction.

Jorge Aguilar
la source
21

À partir des JavaDocs dans https://developer.android.com/reference/android/support/annotation/RequiresApi.html :

[@RequiresApi] Son objectif est similaire à celui de l'ancienne annotation @TargetApi, mais exprime plus clairement qu'il s'agit d'une exigence de l'appelant, plutôt que d'être utilisé pour "supprimer" les avertissements dans la méthode qui dépassent la minSdkVersion.

Je suppose qu'ils sont fonctionnellement équivalents mais @RequiresApisemblent être plus récents et ont plus de chances d'être étendus pour inclure plus de fonctionnalités.

Mike Laren
la source
@Penn Care pour expliquer pourquoi c'est faux?
hamena314
6

Les deux sont destinés à la fonctionnalité de gestion ajoutée aux nouveaux niveaux d'API Android sans affecter les autres niveaux d'API.

Requiert Api

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

Ici, il est dit que l'élément annoté ne doit être appelé qu'au niveau d'API donné ou supérieur. L'élément annoté sous le niveau d'API donné ne sera pas appelé.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Indique que Lint doit traiter ce type comme ciblant un niveau d'API donné, quelle que soit la cible du projet. Destiné uniquement au niveau d'API spécifié. Ne sera pas appelé à un autre niveau d'API.

jeevan venugopal
la source
Quand j'ai utilisé @RequiresApi, AS soulignait un appel de méthode avec du rouge et aussi une classe entière comme contenant une erreur.
CoolMind
@CoolMind avez-vous utilisé "@RequiresApi" dans une méthode?
jeevan venugopal
Non, je l'ai ajouté avant une méthode, comme @TargetApi.
CoolMind
@CoolMind essaie d'utiliser "@RequiresApi" pour la méthode à partir de laquelle vous appelez. Ou entourez l'appel comme ça. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES. * api_code *) {// votre nom de méthode}
jeevan venugopal
Oui, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {ça marche, mais je l'ai déjà dans la méthode. Merci!
CoolMind