RequiresApi vs TargetApi Android-аннотации


98

В чем разница между RequiresApiи TargetApi?

Образец в котлине:

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

ПРИМЕЧАНИЕ: FingerprintManager.AuthenticationCallbackтребуется apiM

ПРИМЕЧАНИЕ 2: если я не использую TargetApi lint, произойдет сбой с ошибкой class requires api level 23...

Ответы:


90

@RequiresApi - Обозначает, что аннотированный элемент должен вызываться только на данном уровне API или выше.

@TargetApi - Указывает, что Lint должен рассматривать этот тип как нацеленный на заданный уровень API, независимо от цели проекта.


48

Сначала я предполагаю, что ваша версия min api ниже, чем api, который вы собираетесь вызвать, потому что именно здесь такие аннотации имеют смысл

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

Когда метод аннотируется этим, каждый раз, когда вы вызываете этот метод, вы получаете красивое красное предупреждение о том, что для этого вызова требуется версия api, которая выше, чем ваша минимальная версия api, но это не мешает вам компилировать и создавать свой apk, это просто вылетит на более низких версиях Android, как я это тестировал.

@TargetApi

Это совсем не помогает, оно подавляет предупреждения о вызове нового apis в вашем методе, но когда вы вызываете этот метод из другого места, предупреждения о ворсинах вообще не появляется, и вы все равно можете собрать и установить свой apk только для удовлетворения сбой при вызове этого метода.


3
Я действительно нашел его более полным и легким для понимания, чем другие ответы, доступные на этой странице. Отсюда +1.
Ананд Кумар Джа

2
Это единственный ответ, который объясняет теория + практика, его действительно следует принять.
Дмитрий Павлухин

37

Подобно тому, что сказал Майк, как вы можете видеть в документации:

Обозначает, что аннотированный элемент должен вызываться только на заданном уровне API или выше.

Это похоже на цель более старой аннотации @TargetApi, но более четко выражает, что это требование к вызывающей стороне, а не используется для «подавления» предупреждений в методе, которые превышают minSdkVersion.

Как вы можете видеть здесь, это фактически заставляет вызывающего абонента проверять API, который использовался при вызове этого метода, вместо того, чтобы просто удалять предупреждение из вашей IDE / LINT.

Вы можете сравнить это с аннотациями @NonNull или @Null, они предписывают, что вызывающий может / не может отправлять нулевые значения в функцию.


21

Из JavaDocs в https://developer.android.com/reference/android/support/annotation/RequiresApi.html :

[@RequiresApi] Это похоже на цель более старой аннотации @TargetApi, но более четко выражает, что это требование к вызывающей стороне, а не используется для «подавления» предупреждений в методе, которые превышают minSdkVersion.

Я полагаю, что они функционально эквивалентны, но @RequiresApiкажутся более новыми и имеют больше шансов на расширение, чтобы включить больше функций.


@Penn Не могли бы вы объяснить, почему это неправда?
hamena314

5

Оба они предназначены для обработки функции, добавленной на новые уровни API Android, не влияя на другие уровни API.

ТребуетсяApi

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

Здесь говорится, что аннотированный элемент должен вызываться только на заданном уровне API или выше. Аннотированный элемент ниже заданного уровня API не будет вызывать.

TargetApi

@TargetApi(Build.VERSION_CODES.*api_code*)

Указывает, что Lint должен рассматривать этот тип как нацеленный на данный уровень API, независимо от цели проекта. Предназначен только для указанного уровня API. Не будет вызывать другой уровень API.


Когда я использовал @RequiresApi, AS подчеркивал вызов метода красным, а также весь класс как содержащий ошибку.
CoolMind

@CoolMind вы использовали "@RequiresApi" внутри какого-либо метода?
дживан венугопал

Нет, я добавил это перед методом, вроде @TargetApi.
CoolMind

@CoolMind попробуйте использовать "@RequiresApi" для метода, из которого вы вызываете. Или окружите призыв вот так. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES. * api_code *) {// имя вашего метода}
jeevan venugopal

Да, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {работает, но в методе уже есть. Благодарность!
CoolMind
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.