Wymaga adnotacji na Androidzie w porównaniu z TargetApi

98

Jaka jest różnica między RequiresApii TargetApi?

Próbka w kotlinie:

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

UWAGA: FingerprintManager.AuthenticationCallbackwymaga interfejsu APIM

UWAGA 2: jeśli nie używam lint TargetApi, wystąpi błąd class requires api level 23...

Daniel Gomez Rico
źródło

Odpowiedzi:

90

@RequiresApi - Wskazuje, że element z adnotacją powinien być wywoływany tylko na danym poziomie interfejsu API lub wyższym.

@TargetApi - Wskazuje, że Lint powinien traktować ten typ jako przeznaczony dla danego poziomu interfejsu API, bez względu na cel projektu.

Abhay
źródło
47

Najpierw założę, że Twoja minimalna wersja api jest niższa niż api, które zamierzasz wywołać, ponieważ to właśnie tam tego rodzaju adnotacje mają sens

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

Gdy metoda jest oznaczona tą adnotacją, za każdym razem, gdy wywołujesz tę metodę, otrzymasz ładne czerwone ostrzeżenie, że to wywołanie wymaga wersji API wyższej niż twoja minimalna wersja api, ale nie powstrzymuje cię to przed kompilacją i budowaniem apk, to po prostu ulegnie awarii na niższych wersjach Androida, gdy go testowałem.

@TargetApi

To wcale nie pomaga, pomija ostrzeżenia o wywołaniu nowego interfejsu API w twojej metodzie, ale kiedy wywołujesz tę metodę z innego miejsca, nie ma żadnego ostrzeżenia o kłaczkach i nadal możesz zbudować i zainstalować swój apk tylko po to, aby spotkać się z awaria, gdy ta metoda jest wywoływana.

ssynhtn
źródło
3
Naprawdę uważam, że jest to bardziej wyczerpujące i łatwiejsze do zrozumienia niż inne odpowiedzi dostępne na tej stronie. Stąd +1.
Anand Kumar Jha
2
To jedyna odpowiedź, która wyjaśnia teorię + praktykę, naprawdę należy ją zaakceptować.
Dmitriy Pavlukhin
37

Podobnie jak powiedział Mike, jak widać w dokumentacji:

Wskazuje, że element z adnotacją powinien być wywoływany tylko na danym poziomie interfejsu API lub wyższym.

Jest to podobne w celu do starszej adnotacji @TargetApi, ale jaśniej wyraża, że ​​jest to wymaganie dla obiektu wywołującego, a nie jest używane do „pomijania” ostrzeżeń w metodzie, które przekraczają minSdkVersion.

Jak widać tutaj, w rzeczywistości wymusza to na wywołującym sprawdzenie API, które zostało użyte podczas wywoływania tej metody, zamiast po prostu usuwać ostrzeżenie z IDE / LINT.

Możesz to porównać z adnotacjami @NonNull lub @Null, które wymuszają, że wywołujący może / nie może wysyłać wartości null do funkcji.

Jorge Aguilar
źródło
21

Z JavaDocs w https://developer.android.com/reference/android/support/annotation/RequiresApi.html :

[@RequiresApi] Jest to podobne w celu do starszej adnotacji @TargetApi, ale jaśniej wyraża, że ​​jest to wymaganie dla obiektu wywołującego, a nie jest używane do "pomijania" ostrzeżeń w metodzie, które przekraczają minSdkVersion.

Przypuszczam, że są funkcjonalnie równoważne, ale @RequiresApiwydają się być nowsze i mają większą szansę na rozszerzenie w celu uwzględnienia większej funkcjonalności.

Mike Laren
źródło
@Penn Care, aby wyjaśnić, dlaczego to nieprawda?
hamena314
5

Oba służą do obsługi funkcji dodanej do nowych poziomów interfejsu API systemu Android bez wpływu na inne poziomy interfejsu API.

Wymaga api

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

Tutaj jest napisane, że element z adnotacjami powinien być wywoływany tylko na danym poziomie API lub wyższym. Element z adnotacjami poniżej podanego poziomu interfejsu API nie zostanie wywołany.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Wskazuje, że Lint powinien traktować ten typ jako przeznaczony dla danego poziomu interfejsu API, bez względu na cel projektu. Przeznaczone tylko dla określonego poziomu API. Nie będzie wywoływany na innym poziomie interfejsu API.

jeevan venugopal
źródło
Kiedy użyłem @RequiresApi, AS podkreślił wywołanie metody kolorem czerwonym, a także całą klasę jako zawierającą błąd.
CoolMind
@CoolMind Czy użyłeś „@RequiresApi” w jakiejkolwiek metodzie?
jeevan venugopal
Nie, dodałem to przed metodą, na przykład @TargetApi.
CoolMind
@CoolMind spróbuj użyć „@RequiresApi” do metody, z której dzwonisz. Albo otoczyć wezwanie w ten sposób. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES. * api_code *) {// nazwa metody}
jeevan venugopal
Tak, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {działa, ale mam to już w metodzie. Dzięki!
CoolMind