Deprecated android что это

Обновлено: 19.09.2024

Аннотация "annotation" в языке Java – это специальная форма синтетических метаданных, которая может быть добавлена в исходный код. Аннотации используются для анализа кода, компиляции или выполнения. Аннотированы могут быть пакеты, классы, методы, переменные и параметры.

Аннотация выполняет следующие функции :

  • предоставляет необходимую информацию для компилятора;
  • предоставляет информацию различным инструментам для генерации другого кода, конфигураций и т. д.;
  • может быть использована во время работы кода.

Встроенные аннотации : @Override, @Deprecated, @SuppressWarnings

Встроенные аннотации отслеживаются средой разработки IDE и применяются к java-коду метода :

@Override Проверка переопределения метода. IDE вызывает предупреждение компиляции, если метод не найден в родительском классе.
@Deprecated IDE отмечает, что метод устарел и вызывает предупреждение компиляции, если метод используется.
@SuppressWarnings Аннотация указывает IDE подавить предупреждения компиляции.

Аннотации, применяемые к другим аннотациям : @Retention, @Documented, @Target, @Inherited

@Retention Определяет, как отмеченная аннотация будет храниться — в коде, в скомпилированном классе или во время работы кода.
@Documented Отмечает аннотацию для включения в документацию.
@Target Отмечает аннотацию как ограничивающую, какие элементы java-аннотации могут быть к ней применены.
@Inherited Отмечает, что аннотация может быть расширенна подклассами аннотируемого класса.

Первоначально в платформе Java имелся механизм, предваряющий механизм аннотаций — например, модификатор transient или тэг @deprecated. В сентябре 2002 года сообществу Java представлен документ JSR-175, описывающий основные тезисы по аннотациям. Он был утвержден в 2004 году. Аннотации стали доступны в самом языке начиная с версии Java 5.0 и описаны в JSR-269. В версии Java 6 аннотации были интегрированы в компилятор javac.

Пример аннотации :

Синтаксис аннотации, @interface

Аннотации представляют из себя дескрипторы, включаемые в текст программы, и используются для хранения метаданных программного кода, необходимых на разных этапах жизненного цикла программы. Информация, хранимая в аннотациях, может использоваться соответствующими обработчиками для создания необходимых вспомогательных файлов или для маркировки классов, полей и т.д. То есть, аннотации могут быть применены к декларациям классов, полей, методов, ну и конечно же аннотаций.

Для описания новой аннотации используется ключевое слово @interface. Например :

Пример использования аннотации Description :

Пример аннотации с параметрами:

В данном примере аннотация включает в себя несколько полей (name, type), которые можно задать как обязательными, так и необязательными. В последнем случае подставляется default значение поля.

Из синтаксиса аннотации следует, что саму аннотацию можно пометить несколькими параметрами. В качестве типов параметров аннотации могут использоваться только примитивные типы, перечисления и класс String. Если у аннотации нет элементов, ее называют маркером (marker annotation type). В этом случае при использовании аннотации круглые скобки можно не писать.

Параметры аннотации

@Retention

Аннотация @Retention позволяет определить жизненный цикл аннотации : будет она присутствовать только в исходном коде, в скомпилированном файле, или она будет также видна и в процессе выполнения. Выбор нужного типа аннотации @Retention зависит от того, как будет использоваться данная аннотацию. Например, генерировать что-то побочное из исходных кодов, или в процессе выполнения "стучаться" к классу через reflection.

@Target

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

@Target(ElementType.PACKAGE)только для пакетов
@Target(ElementType.TYPE)только для классов
@Target(ElementType.CONSTRUCTOR)только для конструкторов
@Target(ElementType.METHOD)только для методов
@Target(ElementType.FIELD)только для атрибутов(переменных) класса
@Target(ElementType.PARAMATER)только для параметров метода
@Target(ElementType.LOCAL_VARIABLE)только для локальных переменных

В случае, если необходимо, что бы аннотация использовалась больше чем для одного типа параметров, то можно указать @Target следующим образом:

В данном случае аннотацию можно использовать только для параметров метода и для локальных переменных.

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

А если в описание аннотации добавить @Documented, получим:

Использование аннотации

Предположим, нам нужно ограничить доступ к некоторым функциям веб-приложения для разных пользователей. Иными словами необходимо реализовать права (permissions). Для этого можно добавить следующее перечисление в класс пользователя:

Создадим аннотацию, которую будем использовать для проверки прав доступа :

Предположим, что у нас есть некоторое действие, право на выполнение которого мы хотим ограничить, например, UserDeleteAction. Для этого добавляем аннотацию на это действие следующим образом:

Теперь используя reflection, можно принимать решение, разрешать или не разрешать выполнение определенного действия :

Пример анализатора аннотации

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

Что должен делать анализатор? Он использует reflection для доступа к аннотируемым данным. Пример анализатора для класса @Test:

Сочетание использования аннотации и reflection позволяет выполнить определенную проверку и вызвать метод на исполнение через invoke. Анализатор готов к использованию. Для использования атрибутов аннотации расширим код.

После получения доступа к атрибуту аннотации определяем ее значение. В нашем случае это значение типа Class, так как expected — это ожидаемая ошибка и мы будем получать exception.

введите сюда описание изображения

В студии это выглядит так:

Вопрос: чем заменять такие методы, и где можно найти актуальные методы которые могут заменить функционал deprecated-метода.


6,078 4 4 золотых знака 24 24 серебряных знака 60 60 бронзовых знаков

Указывают, что заменить можно на Context.getDrawable(int) или getDrawable(int, Theme) , передав тему.

Либо использовать библиотеки совместимости, тогда так: ContextCompat.getDrawable(context, R.drawable.***) , тогда не нужны проверки.

15.7k 1 1 золотой знак 16 16 серебряных знаков 34 34 бронзовых знака

Не забудьте добавить проверку на доступность данного метода в новом API. Например, если новый метод есть только в API 21, то на старых версиях ОС у вас будут ошибки и нужно добавить проверку вида:

15.7k 1 1 золотой знак 16 16 серебряных знаков 34 34 бронзовых знака 5,707 17 17 серебряных знаков 30 30 бронзовых знаков а если в самом методе идет проверку, мне нужно ее дублировать, или нет? public static final Drawable getDrawable(Context context, int id) < final int version = Build.VERSION.SDK_INT; if (version >= 21) < return ContextCompatApi21.getDrawable(context, id); >else < return context.getResources().getDrawable(id); >> Дело в том что этот метод deprecated. Это значит, что в будущих версиях он будет исключен из SDK. Проверка внутри метода немного другое. В вашем случае нужно использовать этот метод если текущий номер API ниже 22 и новый метод, который в ответе выше если уровень API >= 22. я не уточнил, я говорю про метод ContextCompat.getDrawable(‌​) он не deprecated, и в нем внутри происходит проверка! да, ContextCompat можно юзать без проверок. Это класс support library.

Идёте на Android developers в поиске вбиваете свой класс, у которого метод устарел, не забудьте предворительно указать версию API в списке пакетов, далее находите описание класса с его полями, методами и т.д., далее ищите свой метод в списке, в описании метода всегда написано, если он устарел, что лучше использовать вместо него, это касается не только методов, но и в целом любых deprecated.

Там в описании чётко написано, что делать.

3,352 16 16 серебряных знаков 34 34 бронзовых знака

Я использую версию для поддержки старых версий Android.

Когда вы создаете проект с помощью Gradle из командной строки, Lint выводит следующее предупреждение:

Могу ли я аннотировать конкретную строку или метод для отключения предупреждения (поскольку я делаю это специально)? Я не хочу отключать все предупреждения.

ОТВЕТЫ

Ответ 1

Просто что-то новое: не уверен в Android Studio, но, чтобы удалить это предупреждение из этой строки, вы можете использовать:

Это приведет к удалению предупреждения со следующей строки. Например:

Он не покажет ошибку. Однако, как сказал @JJD, это все еще выводит предупреждение на консоль. Но по крайней мере у вас может быть хороший код без ошибок, который может быть полезен, например, для Git. И это предотвращает проблему с @SupressWarnings , которая игнорирует все предупреждения в методе. Поэтому, если у вас есть что-то устаревшее, о котором вы не знаете, @SupressWarnings скроет его, и вы не будете предупреждены. Это преимущество //noinspection

Ответ 2

Я заметил, что встроенная аннотация @SuppressLint("deprecated") больше не будет восприниматься - пока @SuppressWarnings("deprecation") is подбирается.

можно отключить проверки Deprecation для Gradle Linter с помощью lintOptions в файле build.gradle уровня модуля; пока нет возможности определить отдельные файлы следующим образом:

или on может назначить один довольно подробный файл конфигурации lint.xml с помощью LintOptions: lintConfig (при настройках showAll true он все равно будет отображать предупреждения - независимо от предоставленной конфигурации XML):

где можно добавлять отдельные файлы, добавляя их пути:

Исходный код com.android.builder.model.LintOptions может объяснить, что на самом деле там происходит (и подтверждает около 50% того, что я написал).

чтобы избавиться от встроенных предупреждений в Android Studio. этот линтер выглядит как другой линтер - и эти аннотации не влияют на линтер сборки Gradle (может потребоваться использовать его в сочетании с одним из указанных методов выше, чтобы игнорировать известные устаревшие классы и методы):

обновление В заметках о выпуске Android Studio 2.3 упоминается новая функция:

Базовая линия Lint: в Android Studio 2.3 вы можете установить нерешенные предупреждения о задержках в качестве базовой линии в своем проекте. С этого момента Lint будет сообщать только о новых проблемах. Это полезно, если у вас в приложении много проблем с ворсом, но вы просто хотите сосредоточиться на исправлении новых проблем. Узнайте больше о базовой линии Lint и новых проверках Lint & аннотации добавлены в этом выпуске.

здесь объясняется, как создавать предупреждения Lint baseline - который записывает обнаруженные предупреждения в файл XML, а затем отключает их (что намного лучше, чем встроенные аннотации кода, распределенные повсеместно); Я бы предположил, что опции lintConfig и baseline должны быть совместимы (в зависимости от требований).

Ответ 3

У меня возникла аналогичная проблема. Сначала я получил предупреждение о компиляторе:

Что вы можете подавить с помощью @SuppressWarnings("deprecation") или просто игнорировать, поскольку это предупреждение, и это приводит к сбою сборки. Кроме того, я получил ошибку lint (подробности в файле build/lint-results.html ):

Это можно было бы подавить добавлением @SuppressLint("NewApi") . В качестве альтернативы вы можете использовать @TargetApi(13) чтобы намекнуть, что метод/класс могут использовать методы, зависящие от API версии 13, а не то, что вы установили как minSdkVersion (например, 9).

Аннотации могут выполняться только на уровне класса или функции, а не на одной строке. Также обратите внимание, что "девальвация" не должна быть заглавной, а для "NewApi" это, похоже, не имеет значения.

Ответ 4

Вам нужно создать файл lint.xml, чтобы сообщить, что игнорировать.

ваш может выглядеть немного так

Ответ 5

Важен регистр, используйте следующее встроенное или общеклассовое:

Ответ 6

Попробуйте найти метод из ViewCompat , чтобы заменить устаревший метод.

В вашем случае используйте ViewCompat.setBackground(View, Drawable) .

Для таких случаев существует множество классов с именем XXXCompat , таких как ContextCompat , ActivityCompat и так далее.

Ответ 7

Чтобы избежать предупреждений lint, всегда разделяйте функции так, чтобы одна функция имела дело со старой системой, а другая - с новой системой. Старый может безопасно подавить предупреждение. Новый должен быть аннотирован для использования только на новейших уровнях API.

Вот пример того, как это должно выглядеть:

Еще один важный совет, чтобы избежать предупреждений lint: если вы используете весь устаревший класс, вы должны удалить все явные импорты для этого класса. Затем просто получите доступ к этому классу напрямую, используя его полный путь, и делайте это только в старых версиях ваших функций.

И, наконец, вы должны рассмотреть возможность использования androidX, новых библиотек Google, где вы найдете множество универсальных функций, готовых к использованию. Тогда вы можете сэкономить много времени с такими мелкими проблемами. Например, вы можете удалить весь код из приведенного выше примера и просто использовать эту новую и универсальную функцию androidX:

Ответ 8

Просто используйте @SuppressWarnings("deprecation") над функцией, чтобы @SuppressWarnings("deprecation") это конкретное предупреждение только для этой функции.


Безусловно, это было очень удобно, особенно если у вас проект полностью на Kotlin. Однако, мир меняется и теперь нужно искать альтернативы. В этой статье мы кратко рассмотрим, что такое плагин Kotlin Android Extension, какие были проблемы с ним и что теперь нам, Android-разработчикам делать. Частично, использовался материал этой статьи. Итак, поехали.

Кратко о Kotlin Android Extensions

Kotlin Android Extensions — это плагин для Kotlin, позволяющий восстанавливать view из Activities, Fragments, и Views без написания стандартного бойлерплэйт-кода типа findViewById.

Плагин генерирует дополнительный код, который позволяет получить доступ к view в виде XML, так же, как если бы вы имели дело с properties с именем id, который вы использовали при определении структуры.

Также он создаёт локальный кэш view. При первом использовании свойства, плагин выполнит стандартный findViewById. В последующем, view будет восстановлен из кэша, поэтому доступ к нему будет быстрее.

Если это всё так удобно, то зачем его сделали deprecated?

Проблемы Kotlin Android Extensions

  • Используется глобальный нэйминг идентификаторов. Могут возникнуть ситуации, когда один и тот же идентификатор имеется у разных view в разных лэйаутах — соответственно только на этапе работы приложения вы узнаете о том, что использовали не тот id.
  • Возможно использовать только в проектах на Kotlin (кэп)
  • Отсутствует Null Safety. В случае, когда view представлена в одной конфигурации и отсутствует в другой — может возникнуть краш, т.к отсутствует обработка таких ситуаций
  • Невозможно использовать в многомодульных проектах. Очень распространённый сценарий: у вас есть модуль UI Kit, хранящий общие UI-компоненты, которые вы хотите переиспользовать в других модулях. До сих пор висит issues которое вряд ли поправят. В таком сценарии обычно используют старый добрый findViewById :(
  • Резюмируя приведённые недостатки, нетрудно понять, что этот подход не идеален — хотя, безусловно, очень удобен на небольших проектах. На больших проектах с многомодульной архитектурой и сотнями экранов — использование Kotlin Android Extensions уже не кажется идеальным решением.

Альтернативные способы

  • Использование KotterKnife (кек, даже не думайте).
  • Старый добрый FindViewById() — уже получше, но так себе.
  • Использование AndroidAnnotations (привет из 2015)
  • View Binding от Google — бинго!

Итак, победителем в этом списке выглядит ViewBinding от Google (не путайте с DataBinding). Давайте кратко рассмотрим, что это такое.

View Binding — это инструмент, который позволяет проще писать код для взаимодействия с view. При включении View Binding в определенном модуле он генерирует binding классы для каждого файла разметки (layout) в модуле. Объект сгенерированного binding класса содержит ссылки на все view из файла разметки, для которых указан android:id

Главные преимущества View Binding — это Null safety и Type safety.

Начало работы с View Binding

Начать работать с ViewBinding достаточно просто. Нужно добавить опцию в build.gradle:

После этого можно уже использовать.

Каждый сгенерированный binding класс содержит ссылку на корневой view разметки ( root ) и ссылки на все view, которые имеют id. Имя генерируемого класса формируется как "название файла разметки", переведенное в camel case + "Binding".

Например, для файла разметки result_profile.xml :

Будет сгенерирован класс ResultProfileBinding , содержащий 2 поля: TextView name и Button button .

Использование в Activity

Например у вас вот такой layout:

Результат работы ViewBinding:

Использовать viewBinding можно так:

И теперь, после того, как получили ссылки на view:

Если вы используете ViewBinding во фрагменте и держите ссылку на binding во фрагменте (а не только в методе onCreateView()) то не забывайте очищать ссылки в методе onDestroyView(). Пример:

Это необходимо делать из-за жизненного цикла фрагмента и view:


Во время жизни фрагмента, view могут пересоздаваться

В целом, переключиться на ViewBinding достаточно не сложно, хотя и жаль, что Kotlin Android Extensions объявлен deprecated. А я напоминаю, что на практическом онлайн-интенсиве по Android-разработке -вы можете быстро освоить современную Android-разработку с наставником.

Подписывайся на канал чтобы не пропустить анонс и хлопай внизу если статья был полезная.

Понравилась статья? Не забудь подписаться и поставить лайк, а ещё

Читайте также: