Richiede annotazioni Android Api vs TargetApi


98

Qual è la differenza tra RequiresApie TargetApi?

Esempio in kotlin:

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

NOTA: FingerprintManager.AuthenticationCallbackrichiede apiM

NOTA 2: se non utilizzo TargetApi lint fallisce con errore class requires api level 23...

Risposte:


87

@RequiresApi - Indica che l'elemento annotato deve essere chiamato solo al livello API specificato o superiore.

@TargetApi - Indica che Lint dovrebbe trattare questo tipo come target di un determinato livello API, indipendentemente dal target del progetto.


42

Per prima cosa presumo che la tua versione min api sia inferiore all'api che chiamerai, perché è qui che questo tipo di annotazioni ha senso

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

Quando un metodo viene annotato con questo, ogni volta che chiami quel metodo, ricevi un simpatico avviso rosso che questa chiamata richiede una versione api che è superiore alla tua versione min api, ma non ti impedisce di compilare e costruire il tuo apk, esso si bloccherà solo su versioni inferiori di Android mentre l'ho testato.

@TargetApi

Questo non aiuta affatto, sopprime gli avvisi di chiamata di nuove API nel tuo metodo, ma quando chiami questo metodo da qualche altra parte, non viene visualizzato alcun avviso di lanugine e puoi comunque creare e installare il tuo apk solo per incontrare un crash quando viene chiamato quel metodo.


2
L'ho trovato davvero più completo e facile da capire rispetto alle altre risposte disponibili in questa pagina. Quindi +1.
Anand Kumar Jha

1
Questa è l'unica risposta che spiega teoria + pratica, dovrebbe davvero essere accettata.
Dmitriy Pavlukhin

37

Simile a quello che ha detto Mike, come puoi vedere nella documentazione:

Indica che l'elemento annotato deve essere chiamato solo al livello API specificato o superiore.

Questo è simile nello scopo alla vecchia annotazione @TargetApi, ma esprime più chiaramente che questo è un requisito per il chiamante, piuttosto che essere utilizzato per "sopprimere" gli avvisi all'interno del metodo che superano minSdkVersion.

Come puoi vedere qui, questo in realtà impone al chiamante di verificare l'API che è stata utilizzata durante la chiamata a questo metodo, invece di rimuovere semplicemente l'avviso dal tuo IDE / LINT.

Puoi confrontarlo con le annotazioni @NonNull o @Null, che impongono che il chiamante possa / non possa inviare valori null nella funzione.


21

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

[@RequiresApi] Questo è simile nello scopo alla vecchia annotazione @TargetApi, ma esprime più chiaramente che questo è un requisito per il chiamante, piuttosto che essere utilizzato per "sopprimere" gli avvisi all'interno del metodo che superano la minSdkVersion.

Suppongo che siano funzionalmente equivalenti ma @RequiresApisembra essere più recente e ha una maggiore possibilità di essere esteso per includere più funzionalità.


@ Penn Care per spiegare perché questo è falso?
hamena314

6

Entrambi servono per la gestione delle funzionalità aggiunte ai nuovi livelli di API Android senza influire sugli altri livelli API.

Richiede Api

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

Qui si dice che l'elemento annotato deve essere chiamato solo al livello API specificato o superiore. L'elemento annotato al di sotto del livello API specificato non chiamerà.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Indica che Lint dovrebbe trattare questo tipo come target di un determinato livello API, indipendentemente dal target del progetto. Inteso solo per il livello API specificato. Non viene chiamato su un altro livello API.


Quando l'ho usato @RequiresApi, AS ha sottolineato una chiamata al metodo con il rosso e anche un'intera classe come contenente un errore.
CoolMind

@CoolMind hai usato "@RequiresApi" in qualche metodo?
jeevan venugopal

No, l'ho aggiunto prima di un metodo, tipo @TargetApi.
CoolMind

@CoolMind prova a utilizzare "@RequiresApi" per il metodo da cui stai chiamando. Oppure circonda la chiamata in questo modo. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES. * api_code *) {// your method name}
jeevan venugopal

Sì, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {funziona, ma ce l'ho già nel metodo. Grazie!
CoolMind
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.