Support Annotations - аннотации для кода

Support Annotations - аннотации для кода

Начиная с версии 19.1 библиотека Android support library включает себя аннотации, которые помогают улучшить код, уменьшая количество ошибок. Кстати, сама библиотека и многие другие классы системы уже используют новые аннотации в своём коде и вы их можете иногда видеть при наборе своего текста. Количество аннотаций увеличивается, поэтому сверяйтесь с документацией.

По умолчанию аннотации не включены, они идут как отдельная библиотека. Но она входит в состав библиотеки appcompat. Если вы не используете appcompat, то подключите библиотеку аннотаций самостоятельно.

Так как на сегодняшний день проекты по умолчанию используют appcompat, то будем считать, что аннотации всегда готовы к употреблению.

Подсказки с аннотацией появляются при попытке ввести неверный тип параметра в методе, который предусмотрительно снабжён аннотацией.

Аннотации для ресурсов

Для первого знакомства приведу пример с использованием ресурсов. В коде мы часто используем ресурсы строк, изображений, идентификаторов и т.п. По сути ресурс в данном случае является числом типа int. Подготовим ресурсы для имён котов в res/strings.xml

Напишем вспомогательный метод для генерации имени кота, используя строковый ресурс.

Студия не замечает ошибок, метод написан правильно и даже работает.

Но никто вам не помешает написать и такие варианты:

Два варианта используют корректные типы, но результат будет не тот, который мы хотели увидеть. В первом случае выведется путь к ресурсу (к счастью, программа продолжит работу), а во втором произойдёт ужасное - программа пойдёт к коту под хвост.

Как избежать этих ошибок, перепишем метод с добавлением аннотации:

Теперь студия будет подчёркивать неправильные параметры 451 или R.mipmap.ic_launcher и выводить предупреждение, что она ожидает строковые ресурсы, а не любые выдуманные вами числа.

Вы можете использовать аннотации @AnimatorRes, @AnimRes, @AnyRes, @ArrayRes, @AttrRes, @BoolRes, @ColorRes, @DimenRes, @DrawableRes, @FractionRes, @IdRes, @IntegerRes, @InterpolatorRes, @LayoutRes, @MenuRes, @PluralsRes, @RawRes, @StringRes, @StyleableRes, @StyleRes, @XmlRes и т.д. Если у вас есть свой тип ресурсов "foo", то можете использовать аннотацию FooRes.

@NONNULL/@NULLABLE

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

Студия выводит предупреждение, но позволит запустить программу. Нажатие на кнопку и опять ваш труд коту под хвост - крах приложения.

@CheckResult - ожидание результата

Метод может возвращать какое-то значение, которое нужно применить. А можно просто вызвать метод, только какой в этом смысл, если возвращаемое значение нигде не используется? Для тех, кто страдает склерозом - встречайте аннотацию @CheckResult.

Студия укажет на ошибку и откажется запускать ваше приложение. Умница.

Аннотация для продвинутых. ProGuard удаляет неиспользуемые методы при компиляции. Если она делает это ошибочно или по каким-то другим причинам вам нужно оставить метод в приложении, то используйте @Keep:

Аннотации для потоков

Существуют специальные аннотации для указания потоков.

  • @UiThread
  • @MainThread
  • @WorkerThread
  • @BinderThread

Например, мы знаем, что методы класса AsyncTask могут работать только в определённых потоках.

Если в методе doInBackground() обратиться к какому-нибудь компоненту, то студия предупредит, что так делать нельзя.

@UiThread и @MainThread практически совпадают, но в редких случаях могут различаться. Подробности в документации.

Аннотация для цвета

Вы можете задать цвет через ресурс, используя аннотацию @ColorRes. А если перед вами стоит противоположная задача - указать значение цвета через RGB/ARGB, то используйте аннотацию @ColorInt. В этом случае при использовании цветового ресурса студия покажет ошибку.

Диапазон значений

Можно указать диапазон значений для типов float/double через аннотацию @FloatRange:

В этом случае можно использовать значения от 0.0 до 1.0. Любая попытка ввести другое значение приведёт к предупреждению.

Аналогично работает для типов int/long через аннотацию @IntRange:

Для массивов, коллекций и строк можно использовать аннотацию @Size для установки ограничений в размерах или длине строк.

  • Если коллекция не должна быть пустой - @Size(min=1)
  • Максимальная длина строки 15 символов - @Size(max=15)
  • Массив точно состоит из двух элементов - @Size(2)
  • Длина массива должна быть кратна двум (например, координаты точек X и Y) - @Size(multiple=2)
Аннотации для разрешений

Если ваш метод использует функциональность, которая доступна через разрешения, то можете указать через аннотацию @RequiresPermission:

Если имеются несколько подходящих разрешений, то можно использовать атрибут anyOf, чтобы выбрать один из них:

А если нужно выбрать несколько разрешений, то используйте атрибут allOf:

Разрешения для намерений

Если есть разрешения на чтение или запись, то можно указать нужный режим через аннотации @Read или @Write:

Суперкласс

Если метод должен использовать вызов суперкласса, то используем аннотацию @CallSuper:

Остальные аннотации

В документации вы можете узнать о других аннотациях: IntDef/StringDef, @VisibleForTesting и т.д.

📎📎📎📎📎📎📎📎📎📎