Android sdk основные классы

Архитектура Android-приложений. Часть III — основные части приложения

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

В этой статье будут представлены основные «персонажи» архитектуры Android-приложения.

В общем случае, Android-приложение состоит из:

  • Java-классов, являющихся подклассами основных классов из Android SDK (View, Activity, ContentProvider, Service, BroadcastReciever, Intent) и Java-классов, у которых нет родителей в Android SDK.
  • Манифеста приложения
  • Ресурсов наподобие строк, изображений и т.п.
  • Файлов

Java классы

На следующей диаграмме представлена иерархия основных классов из Android SDK, с которыми предстоит иметь дело разработчику:

На самом деле классов намного больше, но это основные. Выделенные жёлтым — те, с которыми разработчик работает непосредственно (в частности, наследуются от них). Остальные так же важны, но они реже используются напрямую.

View — базовый класс для всех виджетов пользовательского интерфейса (GUI widgets). Интерфейс Android-приложения представляет собой дерево экземпляров наследников этого класса. Можно создать это дерево программно, но это неправильно. Пользовательский интерфейс определяется с помощью XML (файлы слоёв, layout files), а во время исполнения автоматически превращается (inflate, термин Android) в дерево соответствующих объектов.

Класс Activity и его подклассы содержат логику, лежащую за пользовательским интерфейсом. При ближайшем рассмотрении этот класс соответствует ViewModel в архитектурном шаблоне Model-View-ViewModel (MVVM). Отношение между подклассом Activity и пользовательским интерфейсом — это отношение один к одному; обычно каждый подкласс Activity имеет только один связанный с ним слой пользовательского интерфейса, и наоборот. Activity имеет жизненный цикл.

В течении жизненного цикла Activity может находиться в одном из трёх состояний:

  • Активно и выполняется — этот пользовательский интерфейс находится на переднем плане (говоря технически — на вершине стека активити)
  • Приостановлено — если данный интерфейс пользователя потерял фокус, но всё ещё видим. В таком состоянии никакой код не выполняется.
  • Завершено — если интерфейс пользователя невидим. В таком состоянии код не выполняется.

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

Класс ContentProvider и его подклассы представляют model в архитектуре MVVM. В большинстве практических случаев это обёртка над базой данных SQLite с немного причудливым способом доступа на основе URI. Теоретически, никто не мешает разработчику создать ContentProvider на основе чего-то ещё, кроме базы данных. Тем не менее, существующий метод query() контент-провайдера возвращает объект Cursor, который крайне похож на JDBC ResultSet интерфейсом и тем, как он работает. Поэтому вряд ли кто-то усомнится, что настоящее назначение контент-провайдеров — инкапсулировать базу данных.

Я не знаю, как комманда Android пришла к такому дизайну, но, по-моему, здесь соединены две хороших, но не слишком совместимых идеи.

И вот почему я так считаю. Основная идея контент-провайдеров, похоже, базируется на архитектуре AJAX приложений. AJAX приложения обычно используют архитектуру MVVM, где модель представлена как URI на стороне сервера (тем не менее, это изменилось с поялвинем HTML5, который позволяет хранить данные локально). В самом деле, тот факт, что контент-провайдеры запрашиваются с помощью URI и создают расширение с помощью типов MIME указывает на то, что в основе лежит AJAX. Напомню, ребята из Google создали большое количество AJAX приложений, таких как Gmail, Google Docs и т.п., поэтому вполне естественно, что идеи заимствовались из архитектуры AJAX.

Возможно, кто-то ещё пришёл с ещё одной отличной идеей: как было бы здорово иметь полноценную реляционную базу на мобильном устройстве! (замечу, это было примерно в 2005 году, когда мобильные телефоны были намного слабее, чем сейчас). И, как результат, они соединили две хороших идеи в один класс ContentProvider. Как это обычно и случается в разработке ПО, соединение двух хороших идей не всегда даёт в результате хорошую идею; в случае Android мы имеем несколько обескураживающий дизайн контент-провайдеров.

Класс Service и его подклассы я затрудняюсь как-то классифицировать. Я думаю, ребята из Google испытывают те же трудности (прочтите, пожалуйста, их документацию). Их классификация, в основном, говорит, чем этот класс не является. Я лично думаю, что сервис — это разновидность Model, обслуживающая несколько иные варианты использования, нежели ContentProvider.

По-моему, архитектурный дизайн Android Service навеян сервисами OSGI.

Думаю, сервисы были созданы ребятами из Google как решение логической проблемы, возникшей из-за модели потоков Android.

Подумайте над этим: Activity активно и выполняется только когда его пользовательский интерфейс находится на переднем плане. Как только интерфейс другого Activity закрывает собой текущее, последнее останавливается, даже если оно что-то делало. А что, если вам нужно выполнять некую операцию, даже если процесс, которые её выполняет, не на переднем плане? С помощью Activity вы не сможете этого сделать. Вы не сможете это сделать и с помощью ContentProvider, поскольку у них нет собственного жизненного цикла, и они могут выполняться только пока Activity, использующее его, активно.

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

Service так же имеет жизненный цикл. Это означает, что он может быть инстанцирован и запущен Android-приложением по некому условию (мы обсудим это позже).

Как я уже упоминал, Service, как model, приследует более общие цели, нежели ContentProvier. Он может использовать базу данных, но его API не связано с БД, как в случае ContentProvider. В большинстве случаев сервисы используются для связи с внешними серверами.

Читайте также:  Сервисы гугл плей можно ли удалить с андроида

Класс BroadcastReceiver и его подклассы представляют собой «подписчика» в механизме взаимодейтсвия издатель/подписчик, реализованном в архитектуре Android.

Мы уже говорили о механизмах взаимодействия в предыдущей статье.

Конечно, разработчик под Android не ограничен одним только расширением классов из Android SDK. Он может писать собственные классы так, как захочет. Но все они будут только хелперами («helper classes») для классов из Andoird SDK.

Манифест Android

Манифест Android — ещё одна важная часть Android-приложения. Идея была навеяна манифестами плагинов для Eclipse.

Манифест Android представляет собой XML файл и выполняет несколько функций. Вот как их описывает Google:

  • Определяет имя Java-пакета приложения. Имя пакета представляет собой уникальный идентификатор для приложения.
  • Описывает компоненты приложения — активити, сервисы, броадкаст-ресиверы и контент-провайдеры. Определяет имена классов, реализующие каждый из компонентов и оглашает их возможности (например, какие Intent-сообщения они могут обрабатывать). Эти объявления позволяют системе Android знать, какие компоненты и при каких условиях могут быть запущены.
  • Предопределяет процессы, которые будут содержать компоненты приложения.
  • Объявляет разрешения, которые приложение должно иметь для доступа к защищённым частям API и взаимодействия с другими приложениями.
  • Также объявляет разрешения, которые требуются для доступа к компонентам приложения.
  • Перечисляет классы Instrumentation, которые предоставляют профайлинг и другую информацию во время работы приложения. Эти объявления присутствуют в манифесте только пока приложение разрабатывается и тестируется; они удаляются перед публикацией приложения.
  • Объявляет минимальный уровень Android API, который требует приложение.
  • Перечисляет библиотеки, с которыми приложение должно быть связано.

Обратите внимание на второй пункт. Имеется ввиду, что если некий класс расширяет Activity, ContentProvider, BroadcastReceiver или Service в вашем приложении, этот класс не может быть использован до тех пор, пока он не описан в манифесте.

Ресурсы

Каждое современное GUI приложение в той или иной форме использует ресурсы. Android-приложения — не исключение. Они используют следующие типы ресурсов:

  • Изображения
  • Слои GUI (XML файлы)
  • Объявления меню (XML файлы)
  • Текстовые строки

Способ, которым ресурсы связываются с Android-приложением — это что-то необычное. Как правило, в Java ресурсы идентифицируются строками. Такие строки могут содержать, например, путь и имя файла, содержащего изображение, или ID данной строки и т.п. Проблема в том, что ошибки в таких ссылках не могут быть обнаружены в процессе трансляции кода.

Давайте рассмотрим следующий пример. Файл с именем mybutton.png содержит картинку для кнопки. Разработчик совершает ошибку и набирает mybuton.png, ссылаясь на ресурс из кода. Как итог, код пытается использовать несуществующий ресурс, но компиляция пройдёт успешно. Ошибка может быть обнаружена только в ходе тестирования (а может и не быть обнаружена вовсе).

Ребята из Google нашли элегантное решение этой проблемы. При сборке Android-приложения генерируется специальный Java-класс с именем R (всего лишь одна буква). Этот класс содержит несколько static final наборов данных. Каждый такой набор данных — ссылка на отдельный ресурс. Эти ссылки используются в коде приложения для связи с ресурсами. Теперь каждая ошибка в ссылке на ресурсы проявляет себя в процессе компиляции.

Файлы

Android-приложение использует несколько разных типов файлов:

  • Файлы «общего назначения»
  • Файлы БД
  • Файлы Opaque Binary Blob (OBB) (они представляют собой зашифрованную файловую систему, которая может быть монтирована для приложения)
  • Закешированные файлы

Хотя, в конечно итоге, все они только файлы Linux, имеет смылсл рассматривать их как отдельные типы файлов только в разрезе обработки их различным API и отдельного хранения. Также они отделены от файлов, хранящихся во внутреннем или внешнем хранилище (последнее может отсутствовать или исчезнуть/появиться в любой момент).

API для работы с файлами реализован классом Context, от которого порождены классы Activity и Service. Этот класс уже обсуждался нами здесь.

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

Источник

Android SDK: Программирование приложения на Java

Наша цель в этой серии — узнать о разработке с помощью AndroidSDK. До сих пор мы изучали инструменты разработки, изучали структуру проекта приложения для Android, начали создавать пользовательский интерфейс и взаимодействие с пользователем. В этом уроке мы рассмотрим основные структуры и концепции языка Java, которые вам нужно знать, чтобы начать разработку приложений для Android.

Введение

Если вы уже знакомы с языком Java, вы можете пропустить этот раздел. Если вы знакомы немного или совсем не знакомы с этим языком, в этом уроке мы рассмотрим, что вам нужно узнать, чтобы продолжить работу с Android. Этого урока недостаточно для того, чтобы научить вас Java с нуля, но он будет работать как пособие для начала работы. Вы должны проходить урок дополнительно изучая Java по мере необходимости.

Мы не будем тратить слишком много времени на детали в этом уроке, но если вы испытываете затруднения с каким-либо понятием, изучите учебные пособия OracleJava. Это обширное руководство по языку, доступное для новичков. Не беспокойтесь, если вы почувствуете себя немного ошеломленным тем, что мы рассмотрим в этом уроке, это обретёт больший смысл после того, как вы начнете внедрять созданные структуры в проекты Android.

1. Синтаксис Java

Шаг 1

Вы уже рассмотрели синтаксис Java в нашем Android-проекте, но для ясности, давайте начнем другой проект. Вместо проекта Android на этот раз мы будем использовать проект Java, чтобы вы могли легко видеть те структуры, которые мы используем. ОткройтеEclipse. Нажмите кнопку «Создать». В появившемся мастере прокрутите вниз до папки Java и разверните её. Выберите «JavaProject» и нажмите «Далее».

Введите «MyJavaProject» в качестве имени проекта и нажмите «Готово». Затем Eclipse создаст новый проект в рабочей области. В Проводнике пакетов разверните новую папку проекта. Щелкните правой кнопкой мыши на «src» и выберите «Создать», затем «Класс». Введите «MyMainClass» в поле «Имя». Установите флажок рядом с «publicstaticvoidmain» и нажмите «Готово».

Eclipse создаст ваш класс и откроет его в редакторе. Не обращайте особого внимания на структуру проекта или на существующий контент класса, потому что ваши проекты Android будут по-разному структурированы. Вы можете использовать этот проект для работы с вашими навыками Java, проще запустить и протестировать код, который вы пишете здесь, чем в приложении для Android, и вы можете сосредоточиться на синтаксисе Java.

Читайте также:  Gish reloaded для андроид

Основным методом является основная строка «publicstaticvoidmain», которую вы видите в файле класса. Независимо от того, что внутри этого метода, это будет выполнено, когда приложение запускается. Содержание метода — это то, что появляется между фигурными скобками после «public static void main (String[] args)». Возможно, Eclipse создаст строку «to do» — просто проигнорируйте ее. Создайте новую строку после нее, и мы добавим туда наш код.

Шаг 2

В Java переменная может сохранять значение, такое как текстовая строка или цифра Когда вы создаете или «объявляете» переменную в Java, вы должны указать тип данных внутри нее и дать ей название. Введите следующее:

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

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

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

Шаг 3

Давайте запустим приложение. Этот процесс немного отличается для приложенийAndroid, но мы поговорим об этом позже в этой серии. Выберите «Запустить», затем «Запустить конфигурации». Выберите «Java-приложение» в списке слева и нажмите кнопку «Новая настройка запуска» над ним. Eclipse автоматически выберет ваше новое приложение Java, если оно единственное, которое у вас есть. В противном случае выберите его, используя кнопку «Обзор».

Нажмите «Запустить», чтобы запустить приложение. Вы должны увидеть номер пять, выписанный в Консоли под редактором. Вы можете использовать этот метод для тестирования кода Java, когда вы его изучаете.

Вы можете запустить проект, который вы запускали недавно, используя кнопку «Запуск» на панели инструментов.

Шаг 4

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

Это перезапишет существующее значение. В Java существует много разных типов переменных. Int называется примитивным типом, наряду с несколькими другими типами чисел, char для символов и boolean, который хранит либо истинное, либо ложное значение. Существуют также тип — Объект; мы рассмотрим объекты позже. Основным типом объекта с которым мы познакомимся будет String, в котором хранится текстовая строка:

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

Добавьте этот код и запустите его, на консоли отобразится: «number:», за которым следует значение переменной.

Шаг 5

Выше мы увидели оператор присваивания «=» — вот несколько других общих операторов:

Операторы могут использоваться как для переменных, так и жёстко установленных чисел (как указано выше):

Шаг 6

Еще одна структура Java, которая важна для Android, — это комментарий. Вы можете добавить комментарий двумя способами:

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

2. Структуры управления

Шаг 1

Код, который мы добавили к основному методу, выполняется при запуске приложения Java. Хотя приложение Android, которое мы создали, будет запущено независимо от того, что содержится в методе onCreate основной активности. Каждая строка внутри этих методов выполняется после предыдущей строки, но поток выполнения не всегда является линейным. В Java есть много контролирующих структур, поэтому давайте рассмотрим некоторые из наиболее распространенных, начиная с условных выражений.

Условные утверждения включают проведение тестов для определения потока исполнения. Самая простая структура в Java — это условие if.

Эти тесты определяют, больше ли значение переменной, чем три. Если это так, строка будет записана для вывода. Если нет, то ничего не будет выписано, и обработка просто переместится на следующую строку в программе. Мы говорим, что тест «возвращает» истинное или ложное значение. Истина и ложь являются логическими значениями. Мы можем добавить else, который выполняется только в том случае, если if возвращает значение false:

Условие else выполняется, если значение равно трем или меньше. Попробуйте код с разными значениями для переменной в виде целого числа, чтобы увидеть результаты тестов. Мы также можем подключить несколько тестов:

Каждый тест выполняется только в том случае, если все предыдущие тесты в цепочке вернулись с ошибкой. Поэтому для любого числа выводится только одна строка. Вы можете связать столько условий else if сколько вам нужно. Вы также можете использовать операторы if, привязанные к одному или нескольким другим условиям else if, без окончательного else.

Мы проверили, что одно число больше другого. Попробуйте следующие варианты:

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

Символы «&&», известные как оператор «and», означает, что вся конструкция вернет true только в том случае, если оба теста возвращают true. Оператор «or» вернет true, если какой-либо тест возвращает true:

Чтобы сгруппировать код в блок, мы можем использовать фигурные скобки — весь код в скобках выполняется, если этот тест возвращает true:

Такие скобки группируют код в циклы, методы и классы.

Шаг 2

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

Первое выражение for инициализирует счётчик в виде числовой переменной равной нулю. Второе выражение является проверкой условия, в том, что переменная меньше десяти. Если проверка возвращает значениеtrue, содержимое цикла выполняется, если нет, то цикл завершится. Как только содержимое цикла выполнено, выполняется третье выражение, увеличивая значение счетчика.

Цикл while использует немного другой синтаксис. Следующий пример обладает тем же эффектом, что и цикл for:

Циклы могут содержать несколько строк кода, включать другие циклы.

Читайте также:  Android view animate scale

Шаг 3

Мы уже разобрались с основным методом и методом Android onCreate. Давайте обратим внимание на создание собственных методов. Поместите следующий метод после закрывающей скобки для основного метода:

Этот метод определяется как открытый, то есть любой класс в проекте может вызвать его обработку. Если это «частный», он доступен только внутри класса (это его уровень видимости). Обычно вам не нужно включать модификатор “static” в ваши первые приложения для Android, поэтому игнорируйте его. Void представляет тип возвращаемых данных. В этом случае метод ничего не возвращает. Чтобы выполнить этот метод, вызовите его в своём основном методе:

Запустите приложение, чтобы увидеть эту функцию. Измените метод, чтобы вернуть значение:

Измените метод, чтобы вернуть значение:

Возвращаемое значение написано. Методы могут также получать параметры:

При вызове метода вы должны передать параметры правильного типа и цифры:

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

3. Классы и объекты

Шаг 1

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

Представьте, что вы создаете игру — вы можете создать класс, предназначенный для обработки деталей пользователя. Выберите пакет приложений в «src» в Проводнике пакетов. Щелкните правой кнопкой мыши и выберите «Создать», затем «Класс». Введите «GameUser» в качестве имени класса, убедитесь, что флажок unchecked/заглушки метода не отмечен и нажмите «Готово». Затем Eclipse откроет файл класса, который изначально имеет в нем только декларацию класса:

Все, что вы добавляете, находится между этими скобками (если вы не добавляете операторы импорта, которые перечислены над этим разделом). Ваше приложениеAndroid обратит внимание, что в файлах классов указано имя пакета выше. Он не указан здесь, потому что мы использовали пакет по умолчанию.

Шаг 2

Внутри класса добавьте пару переменных:

Они называются «переменными экземпляра», потому что они определены для каждого экземпляра класса, который мы создаем. После этого добавьте метод конструктора. Это то, что выполняется, когда объект класса создается:

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

Шаг 3

Класс также может определять методы. Добавьте следующий типичный набор после конструктора:

Они известны как методы get и set, илиgetters и setters, поскольку они предоставляют код, внешний для класса, с возможностью извлечения и установки значений переменных. Просмотрите представление Outline в Eclipse, чтобы узнать, как он может помочь в навигации по содержимому класса.

Шаг 4

Сохраните новый файл класса. Вернитесь в свой основной класс, создайте объект нового класса в основном методе:

Мы передаем параметры, указанные в конструкторе — ключевое слово «new» запустит конструктор. Теперь мы можем использовать этот экземпляр класса для доступа к значениям данных в нем, вызывая его методы:

Запустите программу, чтобы увидеть, как изменяется значение после вызова общедоступных методов объекта. Вы можете создать несколько экземпляров объекта, которые будут управляться отдельно:

4. Наследование и интерфейсы

Шаг 1

Мы видели, как класс определяет совокупности настроек, которые вы можете использовать, создавая экземпляры объектов. Это касается не только создаваемых вами классов, но и существующих классов Java и Android, которые вы также можете использовать. Помимо создания экземпляров классов этих платформ, вы можете расширить их, используя наследование. С помощью наследования вы можете создать класс, который обладает функциональностью существующего класса, а также предоставляет собственную обработку. Мы видели пример в первом проекте Android, который мы создали, с основным классом Activity.

Откройте этот класс. Откройте этот класс. В первой строке класса вы увидите, «extendsActivity». Это означает, что этот класс является подклассом класса ActivityвAndroid. Использование класса Activity позволяет Android обрабатывать детали представления экрана пользователю, используя методы, когда экран находится в разных состояниях (создается, приостанавливается, закрывается и т. д.). Это позволяет сосредоточиться на уникальных моментах приложения, добавляя код в методы, определенные в объявлении класса ActivityвAndroid, и, при необходимости, дополнительные методы.

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

Шаг 2

Посмотрите еще раз на первую строку класса Activity. Помните, что мы добавили код «implementsOnClickListener» для обработки кликов в пользовательском интерфейсе. Это называется внедрением Интерфейса. Интерфейс похож на класс, который вы наследуете при использовании «extends», за исключением того, что в объявлении Интерфейса просто перечислены схемы методов. Вы должны предоставить реализацию метода для каждого из них. Поэтому, когда мы внедрили OnClickListener, мы передали класс для предоставления метода onClick, что мы и сделали. Вы должны предоставить реализацию метода для каждого из них. При наследовании расширяющие классы наследуют реализации метода, предусмотренные в объявлении класса для своего супер класса (расширяемый класс). Вы можете переопределить эти реализации, если вам нужно.

Вывод

В этом уроке мы изложили некоторые существенные особенности синтаксиса Java, которые вам нужно понять. Существует ещё больше структур и понятий, чтобы ознакомиться с ними. Если у вас нет опыта в Java и вы хотите убедиться, что знаете достаточно, чтобы эффективно развиваться в программировании для Android, используйте учебники OracleJava. Темы, которые нужно изучить, включают в себя массивы и операторы switch. Позже внашей серии уроков мы рассмотрим некоторые из наиболее распространенных классов Android, которые вы, скорее всего, будете использовать. В следующей части мы рассмотрим ресурсы в проекте приложения для Android.

Источник

Оцените статью