Статьи

Изучите Java для разработки под Android: основы отражения

В этом уроке вы познакомитесь с концепцией отражения Java: способностью класса или объекта программно исследовать детали своей собственной реализации.

Приложения Android написаны на Java, языке программирования, который поддерживает рефлексию — способность объекта исследовать себя. В этом руководстве вы познакомитесь с основами отражения Java, в том числе с тем, как проверять методы и поля данного класса, проверять наличие определенных методов и другими практическими задачами, которые вам могут понадобиться при разработке для разных версий. Android SDK.

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

Для разработки приложений Android (или любых других приложений Java) вам необходима среда разработки для написания и создания приложений. Eclipse — это очень популярная среда разработки (IDE) для Java и предпочтительная IDE для разработки под Android. Он свободно доступен для операционных систем Windows, Mac и Linux.

Полные инструкции по установке Eclipse (включая поддерживаемые версии) и Android SDK см. На веб-сайте разработчиков Android .

Reflection дает разработчикам возможность проверять и определять характеристики API во время выполнения, а не во время компиляции. В рамках ограничений безопасности, наложенных Java (например, использование public, protected, private), вы можете затем создавать объекты, обращаться к полям и динамически вызывать методы. Java Reflection API доступны как часть пакета java.lang.reflect, который включен в Android SDK для использования разработчиками.

Так какое это имеет отношение к разработке Android? Итак, с каждой новой версией Android SDK классы, интерфейсы, методы и т. Д. Добавляются, обновляются и (реже) удаляются. Тем не менее, разработчики Android часто хотят ориентировать устройства под управлением разных версий Android с помощью простого пакета приложений. Для этого разработчики Android могут использовать методы отражения, чтобы во время выполнения определить, доступен ли определенный класс или метод, прежде чем пытаться его использовать. Это позволяет разработчику использовать новые API там, где они доступны, при этом поддерживая старые устройства — все в одном приложении.

Классы Java представлены во время выполнения с использованием класса Class (java.lang.Class). Этот класс обеспечивает отправную точку для всех API отражений. В этом классе вы найдете много методов для проверки различных аспектов класса, таких как его поля, конструкторы, методы, разрешения и многое другое. Вы также можете использовать метод Class, называемый forName (), чтобы загружать не примитивный класс (например, не int, а Integer) по имени динамически во время выполнения, а не во время компиляции:

Классу (в данном случае NotificationManager) не обязательно иметь соответствующий оператор импорта в вашем коде; вы не компилируете этот класс в свое приложение. Вместо этого загрузчик классов будет динамически загружать класс во время выполнения, если это возможно. Затем вы можете осмотреть этот объект класса и использовать методы отражения, описанные в оставшейся части этого урока.

Вы можете проверить конструкторы, доступные в данном классе. Чтобы получить только общедоступные конструкторы, используйте getConstructors (). Однако, если вы хотите проверить эти методы, специально объявленные в классе, независимо от того, являются ли они открытыми или нет, используйте взамен getDeclaredConstructors (). Оба метода возвращают массив объектов Constructor (java.lang.reflect.Constructor).

Например, следующий код перебирает объявленные конструкторы класса:

Получив действительный объект Constructor, вы можете проверить его параметры и даже объявить новый экземпляр класса, используя этот конструктор с методом newInstance ().

Вы можете проверить поля (или атрибуты), доступные в данном классе. Чтобы получить только общедоступные методы, включая унаследованные поля, используйте getFields (). Однако, если вы хотите проверить эти поля, специально объявленные в классе (а не унаследованные), независимо от того, являются ли они открытыми или нет, используйте взамен getDeclaredFields (). Оба метода возвращают массив объектов Field (java.lang.reflect.Field).

Например, следующий код перебирает объявленные поля класса:

Вы также можете проверить определенное открытое поле по имени, используя метод getField (). Например, чтобы проверить поле EXTRA_CHANGED_PACKAGE_LIST класса Intent (которое было добавлено в API Level 8 или Android 2.2), вы можете использовать:

Получив действительный объект Field, вы можете получить его имя с помощью метода toGenericString (). Если у вас есть соответствующие разрешения, вы также можете получить доступ к значению этого поля класса, используя соответствующие методы get () и set ().

Вы можете проверить методы, доступные в данном классе. Чтобы получить только общедоступные методы, в том числе унаследованные, используйте getMethods (). Однако, если вы хотите проверить эти методы, специально объявленные в классе (без унаследованных), независимо от того, являются ли они открытыми или нет, используйте взамен getDeclaredMethods (). Оба метода возвращают массив объектов метода (java.lang.reflect.Method).

Например, следующий код перебирает объявленные методы класса:

Получив действительный объект Method, вы можете получить его имя с помощью метода toGenericString (). Вы также можете проверить параметры, используемые методом, и исключения, которые он может генерировать. Наконец, если у вас есть соответствующие разрешения, вы также можете вызвать метод с помощью метода invoke ().

Вы можете проверить внутренние классы, определенные в Class, используя метод getDeclaredClasses (). Этот метод возвращает массив объектов Class (java.lang.class), объявленных в родительском классе. Эти классы могут быть проверены, как и любой другой.

Вы также можете проверить флаги и параметры безопасности, называемые модификаторами, связанные с данным классом, полем или методом, используя метод getModifiers (). Интересные модификаторы включают в себя, является ли компонент общедоступным, закрытым, защищенным, абстрактным, окончательным или статическим (среди прочих).

Например, следующий код проверяет модификаторы безопасности класса:

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

Вы также можете проверить метаданные, называемые аннотациями, связанные с данным классом, полем или методом, используя метод getAnnotations (). Интересные метаданные, связанные с классом, могут включать, помимо прочего, информацию об устаревании, предупреждениях и переопределениях.

Например, следующий код проверяет метаданные, доступные для класса AbsoluteLayout. Поскольку этот класс устарел в Android 1.5, одна из возвращаемых аннотаций — @ java.lang.Deprecated (), когда этот код выполняется на Android 2.2:

Аналогично, вы можете просто проверить наличие конкретной аннотации, например, устаревшей, по типу:

Вы также можете использовать отражение, чтобы помочь с отладкой. Например, вы можете использовать ключевое слово class для доступа к данным базового класса для данного типа:

Вы также можете получить информацию о классе из экземпляра переменной, используя метод getClass () класса Object (который, следовательно, наследуется всеми классами в Java):

Если вы хотите проверить класс переменной, лучше использовать instanceof. Смотрите предыдущий урок на instanceof для более подробной информации.

Точно так же вы можете использовать метод getClass () с ключевым словом this, чтобы проверить имя класса, в котором вы находитесь в данный момент, и включить эту информацию как часть вашего журнала отладки в LogCat:

Как вы уже видели, рефлексия может быть очень полезна, особенно если вы не уверены, доступен ли определенный класс или метод во время компиляции. Однако у Reflection есть некоторые недостатки, в том числе снижение производительности и потеря строгой типизации и безопасных методов кодирования, применяемых во время компиляции. Лучше использовать рефлексию экономно, но используйте ее, когда это необходимо.

Reflection — это мощный инструмент, который разработчики Java могут использовать для программного анализа пакетов и API во время выполнения. Хотя операции по отражению обходятся дорого, они дают разработчику гибкость, которая иногда необходима для выполнения работы. Разработчики Android часто используют эти простые методы отражения для проверки доступности определенных классов, интерфейсов, методов и полей во время выполнения, что позволяет им поддерживать различные версии.

Разработчики мобильных приложений Лорен Дарси и Шейн Кондер являются соавторами нескольких книг по разработке Android: углубленная книга по программированию под названием « Разработка беспроводных приложений для Android» и « Разработка Android-приложений Sams TeachYourself за 24 часа» . Когда они не пишут, они тратят свое время на разработку мобильного программного обеспечения в своей компании и оказание консультационных услуг. С ними можно связаться по электронной почте androidwirelessdev+mt@gmail.com , через их блог на androidbook.blogspot.com и в Twitter @androidwireless .

Купить Android-разработку беспроводных приложений, 2-е издание Купить Sam's Teach Yourself для Android-разработки приложений в течение 24 часов Код Мамламбо в Код-Каньоне