пятница, 5 августа 2011 г.

Основы программирования на платформе Android. Часть 2. Архитектура Android. Цикл жизни приложения

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

Архитектура операционной системы Android

В документации к Android написано, что архитектура данной платформы представляет собой программный стек, включающий в себя операционную систему, программное обеспечение промежуточного слоя и основные пользовательские приложения, такие как e-mail, календарь, браузер и т. д. Проще всего рассматривать архитектуру платформы Android  как последовательность уровней. Данная последовательность выглядит так, как показано на рисунке.


Уровень аппаратного обеспечения мы в данном случае обойдём стороной и не будем рассматривать, так как это к делу не относится. Для нас интерес будут представлять уровни, находящиеся выше.

Уровень ядра Linux

В основе операционной системы Android лежит ядро Linux  версии 2.6. Однако стоит заметить, что данное ядро переработано и не является полной копией родительского ядра. На данном уровне происходит управление процессами, распределением памяти и файловой системой. Также в состав ядра входят компоненты для управления энергопотреблением и драйверы устройств на мобильном телефоне. Ядро играет роль слоя абстракции между аппаратным обеспечением и остальным слоем программного обеспечения.

Уровень библиотек и среды исполнения

На данном уровне находятся библиотеки, написанные на языке C/C++. Эти библиотеки отвечают за поддержку различных медиа форматов для прослушивания музыки и просмотра видео и фотографий и многое другое. Вот лишь некоторые библиотеки, которые, как мне кажется, заслуживают особого внимания:

  • OpenGL ES – движок для работы с 3D-графикой на базе OpenGL ES 2.0. Является упрощённой версией OpenGL;
  • SQLite - процессор для работы с базой данных. Важной особенностью является то, что данная СУБД не реализует клиент-серверную архитектуру. Вместо этого движок SQLite компонуется вместе с приложением, то есть фактически становится частью приложения. Именно по причине того, что данная СУБД является встраиваемой, работа с ней осуществляется с довольно высокой скоростью. Сама база данных хранится в одном файле, который существует в одном экземпляре на компьютере, на котором исполняется программа;
  • WebKit - библиотека, предназначенная для работы встроенного в Android Web-браузера;
  • FreeType  – библиотека шрифтов;
  • Media Framework  – библиотека для работы с различными форматами файлов мультимедиа.
На этом же уровне архитектуры Android присутствует ещё одна очень важная и интересная составляющая. Это среда выполнения, представленная виртуальной машиной Dalvik и библиотеками ядра, которые предоставляют функциональность для Java. Dalvik Virtual Machine является одной из реализаций Java-машин, но надо признать что по многим фундаментальным аспектам от неё отличается. Самое главное отличие в том, что Java-машина компании Oracle является стековой, в то время, как Dalvik Virtual Machine является регистровой. Такая реализация была выбрана для увеличения производительности на RISC-архитектурах. Выполняется на данной виртуальной машине не стандартный байт-код Java, а байт-код Dalvik, который имеет формат .dex. Имеется возможность транслировать байт-код формата .class в байт-код формата .dex с помощью утилиты dx, входящую в состав SDK. Также хочется отметить, что, начиная с Android 2.2, Dalvik VM поддерживает JIT-компиляцию, что также положительно сказывается на производительности. Каждый процесс обладает собственной копией Dalvik VM, то есть изнутри Android можно себе представить как множество работающих виртуальных машин Dalvik, на которых выполняются процессы. Этим обеспечивается изолированность процессов друг от друга.

Уровень каркаса приложений

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

Уровень приложений

Самый верхний уровень в архитектуре платформы Android. Его название говорит само за себя. На данном уровне находятся стандартные приложения, входящие в состав системы, а также приложения сторонних разработчиков. Android не делает разницы между «своими» и «чужими» приложениями, поэтому вы можете написать свой календарь и заменить имеющийся в системе.

Жизненный цикл приложения

Сейчас настала пора побеседовать о самих приложениях, что они собой представляют, из чего состоят и сколько живут в системе. Пожалуй, это довольно объёмный вопрос, поэтому придётся запастись терпением. Могу лишь обнадёжить, что многое из этого в учебном проекте, описанном в 1 части, мы использовать не будем, однако знать это будет полезно, как мне кажется.

Начнём с того, что разберёмся с таким важным понятием, как приложение. В любой операционной системой под приложением понимают программу, написанную на некотором языке программирования, которая хранится на диске в виде одного или нескольких файлов и выполняет определённую задачу. На платформе Android приложения обычно пишутся на языке Java, далее запаковываются в файл формата .apk и распространяются на устройства, на которых они смогут выполнять поставленную задачу. Каждое приложение обычно работает в рамках одного процесса. Процессом называется программа во время выполнения, а также ресурсы, необходимые её для работы. На каждый процесс в Android выделен отдельный экземпляр Dalvik VM, как уже писалось выше.

Пока вроде бы всё ясно. Но тут не всё так просто. Дело в том, что приложения в операционной системе Android состоят из компонентов. Как было написано выше, у любого приложения есть возможность использовать ресурсы другого приложения. Это значит, что Вы можете взять готовую часть из одного приложения и запустить в своём так, что пользователь даже не догадается, что это разные приложения, при этом Вам не придётся писать на почту разработчикам понравившейся части приложения и просить их выслать Вам исходный код, а потом добавлять его в свой проект. Вам нужно будет просто запустить нужную часть другого приложения. Правда не стоит сразу раскатывать губу, нужно ещё иметь права на запуск нужной части. Для обеспечения такой функциональности одной точки входа в приложение недостаточно, ведь если Вам понравилась лишь одна формочка из чужого приложения, то Вы же не станете запускать его целиком. Поэтому у приложений Android нет «начала» программы. Поэтому и цикл жизни приложения определить сложно. Зато есть те самые компоненты, у которых есть и «начало» и «конец», именно из них строятся приложения.

Итак, всего существует 4 типа компонентов:
  • Activity  (Деятельность);
  • Service  (Служба);
  • Broadcast Receiver  (Приёмники широковещательных сообщений);
  • Content Provider (Поставщики содержимого).
Приведённые переводы я буду по возможности избегать.

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

Activity – один из важнейших компонентов приложения Android. Является средством непосредственного взаимодействия программы с пользователем. В общем случае Activity – это инструмент, позволяющий пользователю работать с конкретно поставленной задачей. Допустим, у нас имеется приложение для отправки SMS, в таком случае можно для данного приложения определить следующий набор Activity:
  1. Ввод сообщения;
  2. Поля, для ввода номеров контактов, которым будет отправлена SMS;
  3. Список выбора нужных контактов для отправки сообщения.
Этот список можно дополнить, например, выделить Activity для выбора языка. Суть заключается в том, что каждая Activity отвечает за свою задачу, и дальше передаёт эстафету следующему компоненту (не обязательно Activity).

Приложение может состоять как из одного Activity, так и из нескольких. Activity может занимать весь экран, а может и меньше.
 
Так как данный компонент будет для нас иметь первостепенное значение, рассмотрим его жизненный цикл. Перед Вами довольно популярная схема, которая взята из официальной документации.
Запуск Activity является последовательностью вызова некоторых методов. Первым из них всегда является метод onCreate(). Этот метод служит для задания всех необходимых параметров будущей Activity, здесь происходит инициализация переменных и другие подготовительные действия.

Перед тем, как Activity станет видна пользователю вызывается метод onStart(). Перед тем, как начать взаимодействовать с пользователем вызывается метод onResume(), если же приложение становится фоновым, то вызывается метод onStop(). После метода onResume() всегда рано или поздно выполнится метод onPause(). Произойдёт это, когда другая Activity попытается выйти на передний план. Все Activity располагаются в специальном стеке, который так и называется стеком Activity. В данном случае другая Activity попытается занять вершину этого самого стека. В методе onPause() обычно сохраняются все нужные данные и останавливаются анимация и другие вещи, которые загружают центральный процессор. После метода onPause() вызывается либо метод onResume(), либо метод onStop(). Первый вызывается в том случае, если деятельность возвращается на вершину стека Activity. Второй метод вызывается в том случае, если Activity стала невидима пользователю. Далее вызывается либо метод onRestart(), который перезапускает Activity, либо метод onDestroy(), который её уничтожает. После вызова метода onDestroy() жизненный цикл Activity завершается.

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

Broadcast receiver – важный компонент приложения. Сам никогда ничего не делает, но всё знает и слышит, а потому может заставить других сделать нужные вещи за него. Похож на диспетчера из службы заказа пиццы: после звонка диспетчер скорее всего сам не встаёт и не везёт пиццу, он лишь выбирает одного из свободных разносчиков и отдаёт ему поручение с необходимой информацией, о том куда и сколько доставить. Broadcast receiver способен принять сообщение, а потом просто передать их дальше обработчику, чтобы тот мог уже превратить сообщение в нужную информацию и подать сигнал пользователю, если понадобится. Сигналом может быть вибрация устройства, специфический звук, некоторое сообщение (например о том, что заряд батареи на низком уровне) и т. п. То есть в задачу Broadcast receiver входит приём сообщения и реакция на него, которая заключается в передаче необходимых данных другому обработчику, такому как Activity. Также не имеет собственного пользовательского интерфейса.

Content provider – компоненты, служащие для того, чтобы сделать некоторый набор данных доступным для других приложений. Эти данные могут находиться в файловой системе или в базе данных SQLite или хранится другим способом. Контроль за доступом к данным осуществляется посредством разрешений прав доступа. Можно сконфигурировать собственный Content provider и установить необходимые разрешение на нужные наборы данных. Аналогично предыдущим двум типам компонентов не имеет GUI.

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

И ещё одно замечание. Если Вы обратите внимание на левую ветку схемы с изображением жизненного цикла Activity, то можете заметить там блок «Process id killed». Это происходит в том случае, если другому приложению нужна память, а освободить её можно, лишь завершив процесс выполнения. Хочется заметить, что завершается не Activity, а именно процесс, в котором данная Activity была запущена. Завершить процесс Android сможет только после вызова метода onPause(), то есть имеется возможность сохранить все данные, при этом методы onStop() и onDestroy() могут быть не вызваны.

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

вторник, 26 июля 2011 г.

Основы программирования на платформе Android. Часть 1. Основные моменты.

                Всем доброго времени суток! Данный цикл статей целиком и полностью будет посвящён программированию на платформе Android. Данная статья вводная, поэтому здесь я поясню некоторые основные моменты, которые необходимо знать перед тем, как начать создавать полноценные приложения.
                Во-первых, учиться мы будем на примере. Причём конечная система будет работать не только на Android. Мы будем создавать клиент-серверную систему управления заказами. Возможно, вы видели торговых агентов. К нам иногда заходят люди, которые предлагают всякие разные книги. Обычно у них в руках огромная сумка с книгами, которые можно потом будет у них купить. Здесь ситуация примерно такая же, только вместо сумки у торгового агента смартфон с Android на борту. То есть фактически это будет нечто похожее на Интернет-магазин.
                Во-вторых, для полного понимания всего происходящего было бы неплохо, если бы вы изучали статьи тех, кто также работал над этой системой. Вот ссылки на блоги моих друзей, которые также будут писать о своей части сделанной работы – Блог Дмитрия Карташова, Блог Максима Князева. Иногда мы будем повторяться, но я думаю, это будет нечасто, и не такая уж это и проблема. Говорят, что повторение – мать учения. Дмитрий реализовывал сетевую часть на стороне клиента, а также работа над корзиной. Макс работал над серверной частью и работал над приложением для управлением базой данных. В данном цикле статей я буду писать о разработке приложений на Android, не затрагивая сетевую составляющую.

Начальные знания
  
                Для того, чтобы понимать всё написанное, достаточно просто уметь программировать на любом алгоритмическом императивном языке. Хотя, безусловно, знание языка Java помогло бы Вам в изучении программирования под Android. Хотя должен признаться, что, приступая к проекту, никто из нас ничего серьёзного на Java не писал. Но мы писали на аналогичных языках, таких как C++ и C#. Это нам, безусловно, помогло. Поэтому для освоения программирования на платформе Android знание языка Java не является критичным. Во время обучения как раз можно научиться и на Java программировать.

Установка необходимого программного обеспечения

                Нам для работы потребуется следующее ПО:
  • Java Development Kit;
  • IDE Eclipse Java SE;
  • Android SDK;
  • Android Development Tools.
               В качестве IDE можно использовать Eclipse Java EE. Также можно попробовать писать программы на IntelliJ IDEA, в ней имеется плагин для Android, а также можно попробовать NetBeans, который также обладает плагином, который пока что является экспериментальным. Последним пунктом в списке ПО является ADT – плагин для Android под Eclipse.
С установкой JDK проблем возникнуть не должно, просто заходим на сайт, качаем JDK и устанавливаем.
                Далее идём на сайте Eclipse на страницу загрузки, и качаем Eclipse IDE for Java Developers или же Eclipse IDE for Java EE Developers. Первая занимает меньше места. Думаю, всем известно, что Eclipse, обладая некоторым базовым набором инструментов, позволяет легко себя модифицировать и дополнять при помощи различных плагинов. Поэтому можете качать ту, что поменьше, если надо будет, то доставите. Для наших целей вполне подойдёт Eclipse IDE for Java Developers.
                С Android SDK тоже сложного ничего нет, но тут нужно быть чуть внимательнее. Сначала заходим на сайт Android SDK, качаем нужную версию, потом запускаем то, что скачали и ставим. По ходу установки может возникнуть ошибка, что не найдена JRE, хотя мы её поставили. Нажмите Back, а потом снова Next, должно помочь. Теперь самое главное. То, что мы поставили, ещё не SDK. Это всего лишь SDK Manager, с помощью которого нам ещё предстоит загрузить SDK в том виде, какой нам нужен. Это значит, что пакеты для установки вы выбираете сами. Установленные у меня пакеты можно увидеть на рисунке.
                Большая часть из них вам не понадобится. Разрабатывать наше приложение мы будем для платформы Android 2.2, поэтому главное – это иметь у себя SDK Platform Android 2.2, API 8, revision 2. Можете установить документацию и примеры, но это уже для себя.
                Пока ждём, можно открыть Eclipse и поставить плагин ADT. Выбираем в меню Help -> Install New Software… . Далее нажимаем кнопку Add, в поле Name пишем ADT, в поле Location записываем https://dl-ssl.google.com/android/eclipse/ и после этого нажимаем OK. Далее из списка выбираем наш ADT и видим, что у нас в списке устанавливаемого ПО появились Developer Tools. Отлично, нажимаем на «+» и выбираем, что нужно. На первых порах советую установить лишь Android Development Tools. В наших статьях мы не будем использовать остальные инструменты. Могу лишь написать, что они применяются в основном для упрощения проектирования и отладки приложения.
 
                Сделали! Осталась самая малость. Нужно связать Eclipse с Android SDK. Делается это просто. Открываем меню Window -> Preferences, там выбираем Android. Далее нажимаем кнопку Browse и выбираем местоположение Android SDK. Нажимаем «Apply» и получаем список установленных пакетов SDK для разных версий платформы Android.
 
                Настало время опробовать данную стартовую площадку для программирования на Android. Создадим простейший проект Android. Выбираем в меню File -> New project… -> Android project или File -> New project… -> Other…, а там уже дальше Android ->Android project. Нам выпадает окно создания проекта. Указываем имя проекта TestProject, выбираем версию SDK 2.2 и наконец сообщаем имя пакета com.iphoenix.testproject. Можете имя проекта и название пакета указать другими.
 
                Нажатие кнопки Next приведёт к тому, что среда предложит нам создать приложение для тестирования нашей программы на Android. Нам это не нужно, поэтому можно сразу нажать Finish. Вот и всё, приложение создано! Правда, осталось его запустить. Перед запуском необходимо создать виртуальное устройство. Для этого заходим в Window -> Android SDK and AVD Manager. Слева в открывшемся окне выбираем из списка пункт Virtual devices. Нажимаем New и создаём устройство. Нужно указать имя, версию SDK и разрешение экрана. Список поддерживаемых разрешений:

WVGA (800×480)
HVGA (480×320)
QVGA (320×240)
WQVGA (432×240)

            Также поддерживаетя ещё несколько разрешений для выбора и можно указать своё разрешение.
            Также можно добавить карту SD и произвести настройку Hardware. Нам нужно лишь указать имя, версию SDK выбрать Android 2.2 и указать разрешение экрана WVGA800.
Для выбора нужного устройства заходим в свойства проекта Project -> Properties. В списке слева выбираем Run/Debug Settings, выбираем имя нашего проекта, справа нажимаем кнопку Edit. Перед нами открывается окно конфигурации запуска. Заходим на вкладку Target и выбираем наше устройство AVD1.
 
Нажимаем OK. Теперь у нас всё готово для запуска нашего приложения.
Выполняем самые, что ни на есть, привычные для Eclipse действия, нажимаем кнопку Run. На экране появится окно эмулятора, некоторое время нам придётся подождать, пока закончится загрузка. После завершения загрузки необходимо нажать на кнопку Menu на эмуляторе для разблокировки устройства. Ждём несколько секунд и получаем наше первое приложение для платформы Android в окне эмулятора. Уже можно бежать и скидывать его на реальный девайс. Кстати, в каталоге проекта можно зайти в bin, там найти файл TestProject.apk, этот файл и является исполняемым файлом нашего приложения. Хотя признаюсь, сам никогда на реальном устройстве не запускал приложения, но можете попробовать, если есть такая возможность.
 
Пожалуй, хватит на сегодня. В следующей статье рассмотрим вкратце архитектуру Android, работу приложений на данной платформе, а также изучим компоненты приложения. Часть 2 намечается теоретической, но без теории не бывает практики, поэтому стоит немного потерпеть. А дальше начнём разрабатывать нашу систему. Удачи!