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 только для удовлетворения сбой при вызове этого метода.

ssynhtn
источник
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