RequerApi vs TargetApi anotações do Android

98

Qual é a diferença entre RequiresApie TargetApi?

Amostra em kotlin:

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

NOTA: FingerprintManager.AuthenticationCallbackrequer apiM

NOTA 2: se eu não usar o lint TargetApi, falha com erro class requires api level 23...

Daniel Gomez Rico
fonte

Respostas:

87

@RequiresApi - Indica que o elemento anotado só deve ser chamado no nível de API fornecido ou superior.

@TargetApi - Indica que o Lint deve tratar esse tipo como direcionado a um determinado nível de API, independentemente do destino do projeto.

Abhay
fonte
42

Em primeiro lugar, assumirei que sua versão da min api é menor do que a api que você vai chamar, porque é aí que esse tipo de anotação faz sentido

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

Quando um método é anotado com isso, sempre que você chama esse método, você recebe um bom aviso vermelho de que esta chamada requer uma versão da API superior à sua versão da API mínima, mas isso não o impede de compilar e construir seu apk. irá apenas travar em versões anteriores do Android enquanto o testei.

@TargetApi

Isso não ajuda em nada, ele suprime avisos de chamada de novos apis em seu método, mas quando você chama esse método de outro lugar, não há nenhum aviso de lint e você ainda pode construir e instalar seu apk apenas para atender a um travar quando esse método for chamado.

ssynhtn
fonte
2
Eu realmente achei mais abrangente e fácil de entender do que as outras respostas disponíveis nesta página. Portanto, +1.
Anand Kumar Jha
1
Esta é a única resposta que explica teoria + prática, realmente deveria ser aceita.
Dmitriy Pavlukhin
37

Semelhante ao que Mike disse, como você pode ver na documentação:

Indica que o elemento anotado só deve ser chamado no nível de API fornecido ou superior.

Isso é semelhante em propósito à anotação @TargetApi mais antiga, mas expressa mais claramente que isso é um requisito do chamador, em vez de ser usado para "suprimir" avisos dentro do método que excedam minSdkVersion.

Como você pode ver aqui, isso está na verdade obrigando o chamador a verificar a API que foi usada ao chamar este método, em vez de apenas remover o aviso de seu IDE / LINT.

Você pode comparar isso com as anotações @NonNull ou @Null, elas impõem que o chamador pode / não pode enviar valores nulos para a função.

Jorge Aguilar
fonte
21

Dos JavaDocs em https://developer.android.com/reference/android/support/annotation/RequiresApi.html :

[@RequiresApi] Isso é semelhante em finalidade à anotação @TargetApi mais antiga, mas expressa mais claramente que isso é um requisito do chamador, em vez de ser usado para "suprimir" avisos dentro do método que excedem a minSdkVersion.

Suponho que sejam funcionalmente equivalentes, mas @RequiresApiparecem ser mais recentes e têm uma chance maior de serem estendidos para incluir mais funcionalidades.

Mike Laren
fonte
@Penn Se importa em explicar por que isso é falso?
hamena314
6

Ambos são para lidar com o recurso adicionado a novos níveis de API do Android sem afetar os outros níveis de API.

RequerApi

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

Aqui, ele diz que o elemento anotado só deve ser chamado no nível de API fornecido ou superior. O elemento anotado abaixo do nível de API fornecido não chamará.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Indica que o Lint deve tratar esse tipo como direcionado a um determinado nível de API, independentemente do destino do projeto. Significa apenas para o nível de API especificado. Não será chamado em outro nível de API.

jeevan venugopal
fonte
Quando eu usei @RequiresApi, AS sublinhou uma chamada de método com vermelho e também uma classe inteira como contendo um erro.
CoolMind
@CoolMind você usou "@RequiresApi" dentro de algum método?
jeevan venugopal
Não, eu adicionei antes de um método, como @TargetApi.
CoolMind
@CoolMind tente usar "@RequiresApi" para o método do qual você está chamando. Ou cercar a chamada assim. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES. * api_code *) {// nome do seu método}
jeevan venugopal
Sim, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {funciona, mas já tenho no método. Obrigado!
CoolMind