Подробный гайд по разработке Android-приложений с помощью Clean Architecture. Создание Android приложений. Структура Android приложения

Название Описание Необходимость
gen Файлы, сгенерированные самой Java. Здесь находится такой важный файл как R.java Да
AndroidManifest.xml Файл манифеста AndroidManifest.xml предоставляет системе основную информацию о программе. Каждое приложение должно иметь свой файл манифеста Да
src Каталог, в котором содержится исходный код приложения Да
assets Произвольное собрание каталогов и файлов Нет
res Каталог, содержащий ресурсы приложения. В данном каталоге могут находиться подпапки drawable, anim, layout, menu, values, xml и raw (см. ниже) Да

1.5.1. Файл манифеста AndroidManifest.xml

Файл манифеста AndroidManifest.xml предоставляет системе основную информацию о программе. Каждое приложение должно иметь свой файл AndroidManifest.xml. Редактировать файл манифеста можно вручную, изменяя XML-код или через визуальный редактор Manifest Editor, который позволяет осуществлять визуальное и текстовое редактирование файла манифеста приложения.

Назначение файла:

  • описывает компоненты приложения – Activities, Services, Broadcast receivers и Content providers;
  • содержит список необходимых разрешений для обращения к защищенным частям API и взаимодействия с другими приложениями;
  • объявляет разрешения, которые сторонние приложения обязаны иметь для взаимодействия с компонентами данного приложения;
  • объявляет минимальный уровень API Android, необходимый для работы приложения;
  • перечисляет связанные библиотеки.

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

  • является корневым элементом манифеста.

    По умолчанию Eclipse создает элемент с четырьмя атрибутами:

    xmlns:android определяет пространство имен Android.

    package определяет уникальное имя пакета приложения.

    android:versionCode указывает на внутренний номер версии.

    android:versionName указывает номер пользовательской версии.

  • Объявляет разрешение, которое используется для ограничения доступа к определенным компонентам или функциональности данного приложения. В этой секции описываются права, которые должны запросить другие приложения для получения доступа к приложению. Приложение может также защитить свои собственные компоненты (Activities, Services, Broadcast receivers и Content providers) разрешениями. Оно может использовать любое из системных разрешений, определенных Android или объявленных другими приложениями, а также может определить свои собственные разрешения.
  • запрашивает разрешения, которые приложению должны быть предоставлены системой для его нормального функционирования. Разрешения предоставляются во время установки приложения, а не во время его работы.

    Наиболее распространненные разрешения:

    INTERNET – доступ к интернету

    READ_CONTACTS – чтение (но не запись) данных из адресной книги пользователя

    WRITE_CONTACTS – запись (но не чтение) данных в адресную книгу пользователя

    RECEIVE_SMS – обработка входящих SMS

    ACCESS_FINE_LOCATION – точное определение местонахождения при помощи GPS

  • позволяет объявлять совместимость приложения с указанной версией (или более новыми версиями API) платформы Android. Уровень API, объявленный приложением, сравнивается с уровнем API системы мобильного устройства, на который инсталлируется данное приложение.

    Атрибуты:

    android:minSdkVersion определяет минимальный уровень API, требуемый для работы приложения. Система Android будет препятствовать тому, чтобы пользователь установил приложение, если уровень API системы будет ниже, чем значение, определенное в этом атрибуте.

    android:maxSDKVersion позволяет определить самую позднюю версию, которую готова поддерживать программа.

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

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

    Возможные атрибуты:

    android.hardware.camera – требуется аппаратная камера.

    android.hardware.camera.autofocus – требуется камера с автоматической фокусировкой.

  • определяет разрешение экрана, требуемое для функционирования приложения. По умолчанию современное приложение с уровнем API 4 или выше поддерживает все размеры экрана и должно игнорировать этот элемент.
  • один из основных элементов манифеста, содержащий описание компонентов приложения. Содержит дочерние элементы ( , , , И другие), которые объявляют каждый из компонентов, входящих в состав приложения. В манифесте может быть только один элемент .

1.5.2. Ресурсы

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

В основном, ресурсы хранятся в виде XML-файлов в каталоге res с подкаталогами values, drawable-ldpi, drawable-mdpi, drawable-hdpi, layout. Но также бывают еще два типа ресурсов: raw и assets.

Для удобства система создает идентификаторы ресурсов и использует их в файле R.java (класс R, который содержит ссылки на все ресурсы проекта), что позволяет ссылаться на ресурсы внутри кода программы. Статический класс R генерируется на основе заданных ресурсов и создается во время компиляции проекта. Так как файл R генерируется автоматически, то нет смысла его редактировать вручную, потому что все изменения будут утеряны при повторной генерации.

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

Самыми распространенными ресурсами являются, пожалуй, строки (string), цвета (color) и графические рисунки (bitmap).

В следующей таблице перечислены основные ресурсы Android-приложения:

Тип ресурса Размещение Описание
Цвета /res/colors/ Идентификатор цвета, указывающий на цветовой код.
Строки /res/strings/ Строковые ресурсы. В их число также входят строки в формате java и html.
Меню /res/menus/ Меню в приложении можно задать как XML-ресурсы.
Параметры /res/values/ Представляет собой параметры или размеры различных элементов.
Изображения /res/drawable/ Ресурсы-изображения. Поддерживает форматы JPG, GIF, PNG (самый предпочтительный) и другие. Каждое изображение является отдельным файлом. Система также поддерживает stretchable images, в которых можно менять масштаб отдельных элементов, а другие элементы оставлять без изменений.

Отрисовываемые цвета

/res/values/

/res/drawable/

Представляет цветные прямоугольники, которые используются в качестве фона основных отрисовываемых объектов, например точечных рисунков.
Анимация /res/anim/ Android может выполнить простую анимацию на графике или на серии графических изображений.
Произвольные XML-файлы /res/xml/ В Android в качестве ресурсов могут использоваться произвольные XML-файлы.
Произвольные необработанные ресурсы /res/raw/ Любые нескомпилированные двоичные или текстовые файлы, например, видео.

Помимо изображений в каталоге res/drawable могут храниться ресурсы простых геометрических фигур. Вот лишь некоторые из возможных атрибутов:

  • android:shape задает тип фигуры: rectangle (прямоугольник), oval (овал), line (линия), ring (окружность);
  • создает закругленные углы для прямоугольника;
  • задает градиентную заливку для фигуры; в Android можно создавать три типа градиентов: Linear (линейный), Radial (радиальный) и Sweep (разверточный);
  • задает размеры фигуры;
  • задает сплошной цвет для фигуры.

Анимация в Android бывает двух видов:

  • Frame Animation – кадровая анимация, традиционная анимация при помощи быстрой смены последовательных изображений, как на кинопленке.
  • Tween Animation – анимация преобразований может выполняться в виде ряда простых преобразований: изменение позиции (класс TranslateAnimation), размера (ScaleAnimation), угла вращения (RotateAnimation) и уровня прозрачности (AlphaAnimation). Команды анимации определяют преобразования, которые необходимо произвести над объектом. Преобразования могут быть последовательными или одновременными. Последовательность команд анимации определяется в XML-файле (предпочтительно) или в программном коде.

В Android имеется еще один каталог, в котором моrут храниться файлы, предназначенные для включения в пакет – /assets . Это не ресурсы, а просто необработанные файлы. Этот каталог находится на том же уровне, что и /res. Для файлов, располагающихся в /assets, в R.java не генерируются идентификаторы ресурсов. Для их считывания необходимо указать путь к файлу. Путь к файлу является относительным и начинается с /assets. Этот каталог, в отличие от подкаталога res/, позволяет задавать произвольную глубину подкаталогов и произвольные имена файлов.

1.5.3. Разметка

В Android-приложениях, пользовательский интерфейс построен на View и ViewGroup объектах. Класс ViewGroup является основой для подкласса Layout (разметка).

Разметка (также используются термины компоновка или макет) хранится в виде XML-файла в папке /res/layout . Это сделано для того, чтобы отделить код от дизайна, как это принято во многих технологиях (HTML и CSS, Visual Studio и Expression Blend). Кроме основной компоновки для всего экрана, существуют дочерние компоновки для группы элементов. По сути, компоновка – это некий визуальный шаблон для пользовательского интерфейса приложения, который позволяет управлять элементами, их свойствами и расположением. В своей практике вам придется познакомиться со всеми способами размещения.

Android-плагин для Eclipse включает в себя специальный редактор для создания разметки двумя способами. Редактор имеет две вкладки: одна позволяет увидеть, как будут отображаться элементы управления, а вторая – создавать XML-разметку вручную.

Создавая пользовательский интерфейс в XML-файле, можно отделить дизайн приложения от программного кода. Можно изменять пользовательский интерфейс в файле разметки без необходимости изменения программного кода. Например, можно создавать XML-разметки для различных ориентаций экрана мобильного устройства (portrait, landscape), размеров экрана и языков интерфейса. Впрочем, элементы интерфейса можно создавать и программно, когда это необходимо.

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

Существует несколько стандартных типов разметок:

  • FrameLayout является самым простым типом разметки. Обычно это пустое пространство на экране, которое можно заполнить только дочерним объектом View или ViewGroup . Все дочерние элементы FrameLayout прикрепляются к верхнему левому углу экрана. В разметке FrameLayout нельзя определить различное местоположение для дочернего объекта View. Последующие дочерние объекты View будут просто рисоваться поверх предыдущих представлений, частично или полностью затеняя их, если находящийся сверху объект непрозрачен
  • LinearLayout выравнивает все дочерние объекты в одном направлении – вертикально или горизонтально. Направление задается при помощи атрибута ориентации android:orientation . Все дочерние элементы помещаются в стек один за другим, так что вертикальный список представлений будет иметь только один дочерний элемент в строке независимо от того, насколько широким он является. Горизонтальное расположение списка будет размещать элементы в одну строку с высотой, равной высоте самого высокого дочернего элемента списка.
  • TableLayout позиционирует свои дочерние элементы в строки и столбцы. TableLayout не отображает линии обрамления для рядов, столбцов или ячеек. TableLayout может иметь ряды с разным количеством ячеек. При формировании разметки таблицы некоторые ячейки при необходимости можно оставлять пустыми. TableLayout удобно использовать, например, при создании логических игр типа Судоку, Крестики-Нолики и тому подобных.
  • RelativeLayout позволяет дочерним элементам определять свою позицию относительно родительского представления или относительно соседних дочерних элементов.

Все описываемые разметки являются подклассами ViewGroup и наследуют свойства, определенные в классе View.

Разметки ведут себя как элементы управления, и их можно группировать. Расположение элементов управления может быть вложенным. Например, можно использовать RelativeLayout в LinearLayout и так далее. Однако, слишком большая вложенность элементов управления вызывает проблемы с производительностью.

Следует начать с того что все приложения для ОС Android распространяются в виде инсталляционных пакетов - файлов с расширением APK.

APK (Android Package) -- формат архивных исполняемых файлов-приложений для Android.

Каждое приложение Android скомпилировано и упаковано в один файл, который включает в себя весь код приложения (.DEX файлы), ресурсы, активы и файл manifest. Файл приложения может иметь любое имя, но расширение должно быть.APK. Например: myAppFile.apk.

Файлы с данным расширением хранятся в магазине Google Play, и загружаются с его помощью в смартфон для их использования, либо устанавливаются пользователем вручную на устройстве.

Файлы этого формата не шифруются, являются подмножеством формата архива ZIP.

Каждый.APK файл -- это сжатый архив для исполнения в DalvikVM (виртуальная машина), который может быть установлен не только на операционной системе Android.

APK файл как архив обычно содержит следующие директории:

· META-INF:

§ MANIFEST.MF: манифест файл

§ CERT.RSA: сертификат приложения

§ CERT.SF: список ресурсов и их SHA1 хеш-сумма например на Рисунке 6:

· Signature-Version: 1.0

· Created-By: 1.0 (Android)

· SHA1-Digest-Manifest: wxqnEAI0UA5nO5QJ8CGMwjkGGWE=

· Name: res/layout/exchange_component_back_bottom.xml

· SHA1-Digest: eACjMjESj7Zkf0cBFTZ0nqWrt7w=

· Name: res/drawable-hdpi/icon.png

· SHA1-Digest: DGEqylP8W0n0iV/ZzBx3MW0WGCA=

Рисунок 6. Структура файла со списком ресурсов и их хеш-сумм.

· Директория lib: содержит скомпилированный исполняемый код адаптированный под различные типы процессоров, обычно разделена на следующие директории:

Ш armeabi: код только для ARM процессоров

Ш armeabi-v7a: код для для процессоров ARMv7 и ниже только.

Ш x86: скомпилированный код только для архитектуры x86

Ш mips: скомпилированный код только для архитектуры MIPS

· Директория res: директория содержит файлы ресурсы не вошедшие в файл resources.arsc(см. ниже)

· Директория assets: содержит активы которые могут получены с помощью AssetManager

· Файл AndroidManifest.xml: дополнительный манифест файл, описывающий версию приложения, разрешения, используемые библиотеки. Как правило это файл идёт в формате binary XML, это формат файлов можно привести к читаемому виду с помощью сторонних утилит таких как AXMLPrinter2, apktool, или Androguard.

· Файл classes.dex: исполняемый файл виртуальной машины Dalvik, полученный путём преобразования скомпилированных JAVA классов с помощью утилиты DX. Утилита входит в состав Android SDK.

· Файл resources.arsc: файл содержит пре-компилированные ресурсы, например в виде бинарных XML файлов.

Из всего выше обозначенного в данной работе при анализе уровня опасности будут использоваться только два файла это AndroidManifest.xml и classes.dex. Ни их структуре остановимся более подробно.

AndroidManifest.xml

Данный файл, как уже говорилось ранее, содержит информацию о приложении, в том числе список требуемых разрешений приложения. В том числе на основе этих данных можно ранжировать уровень опасности приложения. Обратимся как его структуре: в первую очередь необходимо отметить что в установочном пакете androidmanifest.xml имеет бинарный вид, то есть преобразованный xml, хотя в оригинальном состоянии этот файл имеет структуру, обозначенную на Рисунке 7:

Рисунок 7. Подтверждение установки приложения из стороннего источника.

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

В Таблице 1 приведены некоторые разрешения которые представляют наибольшую опасность:

Таблица 1. Описание некоторых опасных разрешений в ОС Android.

ACCESS_COARSE_LOCATION

Приложение сможет получить доступ к приблизительному местоположению, полученному из сетевого расположения источников, таких как вышки сотовой связи и Wi-Fi.

ACCESS_FINE_LOCATION

Приложение сможет получить доступ к точному местоположению от места расположения источников, таких как GPS, вышек сотовой связи и Wi-Fi.

CALL_PHONE

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

Приложение сможет сделать снимок встроенной камерой

DELETE_PACKAGES

Позволяет приложению удалять пакеты.

DEVICE_POWER

Позволяет приложению отключить питание устройства

Как видно из описаний некоторые разрешения можно группировать, выставив при этом уровень опасности целой группе функций, например разрешения READ_SMS, BRICK являются очень опасными и им можно присвоить уровень опасности 10(максимальный). Это вызвано тем, что под разрешением READ_SMS понимается чтение личных данных пользователей, что является потенциально опасным для пользователя действием со стороны приложения. Под BRICK понимается отключение устройства в целом - что тоже очень опасно для пользователя потому что устройство полностью прекращает свою работу.

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

Данный файл носит в себе основной функционал приложения, содержит байт-код, понятный виртуальной машине Dalvik. Имеет следующую внутреннюю структуру, представленную в Таблице 2:

Таблица 2. Структура Dex файла.

На самом деле это файл, содержащий в себе программный код для виртуальной машины Dalvik. Приложения для Android пишутся на языке Java, но после компиляции кода в.class-файлы, вызывается утилита dx, которая транслирует их в один файл classes.dex, являющийся основной составляющей APK файла. Общий алгоритм формирования dex представлен на Рисунке 8.


Рисунок 8. Механизм формирования файла classes.dex.

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

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

Тебя никогда не интересовало, как работают fastboot или ADB? Или почему смартфон под управлением Android практически невозможно превратить в кирпич? Или, может быть, ты давно хотел узнать, где кроется магия фреймворка Xposed и зачем нужны загрузочные скрипты /system/etc/init.d? А как насчет консоли восстановления (recovery)? Это часть Android или вещь в себе и почему для установки сторонней прошивки обычный рекавери не подходит? Ответы на все эти и многие другие вопросы ты найдешь в данной статье.

Как работает Android

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

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

Шаг первый. ABOOT и таблица разделов

Все начинается с первичного загрузчика. После включения питания система исполняет код загрузчика, записанного в постоянную память устройства. Затем он передает управление загрузчику aboot со встроенной поддержкой протокола fastboot, но производитель мобильного чипа или смартфона/планшета имеет право выбрать и любой другой загрузчик на его вкус. Например, компания Rockchip использует собственный, несовместимый с fastboot загрузчик, для перепрограммирования и управления которым приходится использовать проприетарные инструменты.

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

Получив управление, aboot проверяет таблицу разделов и передает управление ядру, прошитому в раздел с именем boot, после чего ядро извлекает в память RAM-образ из того же раздела и начинает загрузку либо Android, либо консоли восстановления. NAND-память в Android-устройствах поделена на шесть условно обязательных разделов:

  • boot - содержит ядро и RAM-диск, обычно имеет размер в районе 16 Мб;
  • recovery - консоль восстановления, состоит из ядра, набора консольных приложений и файла настроек, размер 16 Мб;
  • system - содержит Android, в современных девайсах имеет размер не менее 1 Гб;
  • cache - предназначен для хранения кешированных данных, также используется для сохранения прошивки в ходе OTA-обновления и поэтому имеет размер, сходный с размерами раздела system;
  • userdata - содержит настройки, приложения и данные пользователя, ему отводится все оставшееся пространство NAND-памяти;
  • misc - содержит флаг, определяющий, в каком режиме должна грузиться система: Android или recovery.

Кроме них, также могут существовать и другие разделы, однако общая разметка определяется еще на этапе проектирования смартфона и в случае aboot зашивается в код загрузчика. Это значит, что: 1) таблицу разделов нельзя убить, так как ее всегда можно восстановить с помощью команды fastboot oem format; 2) для изменения таблицы разделов придется разлочить и перепрошить загрузчик с новыми параметрами. Из этого правила, однако, бывают исключения. Например, загрузчик того же Rockchip хранит информацию о разделах в первом блоке NAND-памяти, так что для ее изменения перепрошивка загрузчика не нужна.

Особенно интересен раздел misc. Существует предположение, что изначально он был создан для хранения различных настроек независимо от основной системы, но в данный момент используется только для одной цели: указать загрузчику, из какого раздела нужно грузить систему - boot или recovery. Эту возможность, в частности, использует приложение ROM Manager для автоматической перезагрузки системы в recovery с автоматической же установкой прошивки. На ее же основе построен механизм двойной загрузки Ubuntu Touch, которая прошивает загрузчик Ubuntu в recovery и позволяет управлять тем, какую систему грузить в следующий раз. Стер раздел misc - загружается Android, заполнил данными - загружается recovery… то есть Ubuntu Touch.

Шаг второй. Раздел boot

Если в разделе misc не стоит флаг загрузки в recovery, aboot передает управление коду, расположенному в разделе boot. Это не что иное, как ядро Linux; оно находится в начале раздела, а сразу за ним следует упакованный с помощью архиваторов cpio и gzip образ RAM-диска, содержащий необходимые для работы Android каталоги, систему инициализации init и другие инструменты. Никакой файловой системы на разделе boot нет, ядро и RAM-диск просто следуют друг за другом. Содержимое RAM-диска такое:

  • data - каталог для монтирования одноименного раздела;
  • dev - файлы устройств;
  • proc - сюда монтируется procfs;
  • res - набор изображений для charger (см. ниже);
  • sbin - набор подсобных утилит и демонов (adbd, например);
  • sys - сюда монтируется sysfs;
  • system - каталог для монтирования системного раздела;
  • charger - приложение для отображения процесса зарядки;
  • build.prop - системные настройки;
  • init - система инициализации;
  • init.rc - настройки системы инициализации;
  • ueventd.rc - настройки демона uventd, входящего в состав init.

Это, если можно так выразиться, скелет системы: набор каталогов для подключения файловых систем из разделов NAND-памяти и система инициализации, которая займется всей остальной работой по загрузке системы. Центральный элемент здесь - приложение init и его конфиг init.rc, о которых во всех подробностях я расскажу позже. А пока хочу обратить внимание на файлы charger и ueventd.rc, а также каталоги sbin, proc и sys.

Файл charger - это небольшое приложение, единственная задача которого - вывести на экран значок батареи. Он не имеет никакого отношения к Android и используется тогда, когда устройство подключается к заряднику в выключенном состоянии. В этом случае загрузки Android не происходит, а система просто загружает ядро, подключает RAM-диск и запускает charger. Последний выводит на экран иконку батареи, изображение которой во всех возможных состояниях хранится в обычных PNG-файлах внутри каталога res.

Файл ueventd.rc представляет собой конфиг, определяющий, какие файлы устройств в каталоге sys должны быть созданы на этапе загрузки системы. В основанных на ядре Linux системах доступ к железу осуществляется через специальные файлы внутри каталога dev, а за их создание в Android отвечает демон ueventd, являющийся частью init. В нормальной ситуации он работает в автоматическом режиме, принимая команды на создание файлов от ядра, но некоторые файлы необходимо создавать самостоятельно. Они перечислены в ueventd.rc.

Каталог sbin в стоковом Android обычно не содержит ничего, кроме adbd, то есть демона ADB, который отвечает за отладку системы с ПК. Он запускается на раннем этапе загрузки ОС и позволяет выявить возможные проблемы на этапе инициализации ОС. В кастомных прошивках в этом каталоге можно найти кучу других файлов, например mke2fs, которая может потребоваться, если разделы необходимо переформатировать в ext3/4. Также модеры часто помещают туда BusyBox, с помощью которого можно вызвать сотни Linux-команд.

Каталог proc для Linux стандартен, на следующих этапах загрузки init подключит к нему procfs, виртуальную файловую систему, которая предоставляет доступ к информации обо всех процессах системы. К каталогу sys система подключит sysfs, открывающую доступ к информации о железе и его настройкам. С помощью sysfs можно, например, отправить устройство в сон или изменить используемый алгоритм энергосбережения.

Файл build.prop предназначен для хранения низкоуровневых настроек Android. Позже система обнулит эти настройки и перезапишет их значениями из недоступного пока файла system/build.prop.


Выносы из текста

  • Fastboot останется на месте, даже если в результате экспериментов ты сотрешь со смартфона содержимое всех разделов NAND-памяти
  • Раздел recovery полностью самодостаточен и содержит миниатюрную операционную систему, которая никак не связана с Android
  • Слегка изменив файл fstab, мы можем заставить init загрузить систему с карты памяти

Шаг второй, альтернативный. Раздел recovery

В том случае, если флаг загрузки recovery в разделе misc установлен или пользователь включил смартфон с зажатой клавишей уменьшения громкости, aboot передаст управление коду, расположенному в начале раздела recovery. Как и раздел boot, он содержит ядро и RAM-диск, который распаковывается в память и становится корнем файловой системы. Однако содержимое RAM-диска здесь несколько другое.

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

В стандартном (стоковом) recovery таких функций обычно всего три: установка подписанных ключом производителя смартфона прошивок, вайп и перезагрузка. В модифицированных сторонних recovery, таких как ClockworkMod и TWRP, функций гораздо больше. Они умеют форматировать файловые системы, устанавливать прошивки, подписанные любыми ключами (читай: кастомные), монтировать файловые системы на других разделах (в целях отладки ОС) и включают в себя поддержку скриптов, которая позволяет автоматизировать процесс прошивки и многие другие функции.

С помощью скриптов, например, можно сделать так, чтобы после загрузки recovery автоматически нашел на карте памяти нужные прошивки, установил их и перезагрузился в Android. Эта возможность используется инструментами ROM Manager, auto-flasher, а также механизмом автоматического обновления CyanogenMod и других прошивок.

Кастомные рекавери также поддерживают скрипты бэкапа, располагающиеся в каталоге /system/addon.d/. Перед прошивкой recovery проверяет наличие скриптов и выполняет их перед тем, как произвести прошивку. Благодаря таким скриптам gapps не исчезают после установки новой версии прошивки.

Команды fastboot

Чтобы получить доступ к fastboot, необходимо установить Android SDK, подключить смартфон к ПК с помощью кабеля и включить его, зажав обе кнопки громкости. После этого следует перейти в подкаталог platform-tools внутри SDK и запустить команду

Fastboot devices

На экран будет выведено имя устройства. Другие доступные команды:

  • fatsboot oem unlock - разлочка загрузчика на нексусах;
  • update файл.zip - установка прошивки;
  • flash boot boot.img - прошивка образа boot-раздела;
  • flash recovery recovery.img - прошивка образа раздела recovery;
  • flash system system.img - прошивка образа системы;
  • oem format - восстановление разрушенной таблицы разделов;

Шаг третий. Инициализация

Итак, получив управление, ядро подключает RAM-диск и по окончании инициализации всех своих подсистем и драйверов запускает процесс init, с которого начинается инициализация Android. Как я уже говорил, у init есть конфигурационный файл init.rc, из которого процесс узнает о том, что конкретно он должен сделать, чтобы поднять систему. В современных смартфонах этот конфиг имеет внушительную длину в несколько сот строк и к тому же снабжен прицепом из нескольких дочерних конфигов, которые подключаются к основному с помощью директивы import. Тем не менее его формат достаточно простой и по сути представляет собой набор команд, разделенных на блоки.

Каждый блок определяет стадию загрузки или, выражаясь языком разработчиков Android, действие. Блоки отделены друг от друга директивой on, за которой следует имя действия, например on early-init или on post-fs. Блок команд будет выполнен только в том случае, если сработает одноименный триггер. По мере загрузки init будет по очереди активировать триггеры early-init, init, early-fs, fs, post-fs, early-boot и boot, запуская таким образом соответствующие блоки команд.


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

Наиболее примечательный из дополнительных конфигов носит имя initrc.имя_устройства.rc, где имя устройства определяется автоматически на основе содержимого системной переменной ro.hardware. Это платформенно-зависимый конфигурационный файл, который содержит блоки команд, специфичные для конкретного устройства. Кроме команд, отвечающих за тюнинг ядра, он также содержит примерно такую команду:

Mount_all ./fstab.имя_устройства

Она означает, что теперь init должен подключить все файловые системы, перечисленные в файле./fstab.имя_устройства, который имеет следующую структуру:

Имя_устройства_(раздела) точка_монтирования файловая_система опции_фс прочие опции

Обычно в нем содержатся инструкции по подключению файловых систем из внутренних NAND-разделов к каталогам /system (ОС), /data (настройки приложений) и /cache (кешированные данные). Однако слегка изменив этот файл, мы можем заставить init загрузить систему с карты памяти. Для этого достаточно разбить карту памяти на три 4 раздела: 1 Гб / ext4, 2 Гб / ext4, 1 Гб / ext4 и оставшееся пространство fat32. Далее необходимо определить имена разделов карты памяти в каталоге /dev (для разных устройств они отличаются) и заменить ими оригинальные имена устройств в файле fstab.


В конце блока boot init, скорее всего, встретит команду class_start default, которая сообщит, что далее следует запустить все перечисленные в конфиге службы, имеющие отношение к классу default. Описание служб начинается с директивы service, за которой следует имя службы и команда, которая должна быть выполнена для ее запуска. В отличие от команд, перечисленных в блоках, службы должны работать все время, поэтому на протяжении всей жизни смартфона init будет висеть в фоне и следить за этим.

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

Команды init.rc

Процесс init имеет встроенный набор команд, многие из которых повторяют стандартный набор команд Linux. Наиболее примечательные из них:

  • exec /путь/до/команды - запустить внешнюю команду;
  • ifup интерфейс - поднять сетевой интерфейс;
  • class_start имя_класса - запустить службы, относящиеся к указанному классу;
  • class_stop имя_класса - остановить службы;
  • insmod /путь/до/модуля - загрузить модуль ядра;
  • mount ФС устройство каталог - подключить файловую систему;
  • setprop имя значение - установить системную переменную;
  • start имя_службы - запустить указанную службу;
  • trigger имя - включить триггер (выполнить указанный блок команд);
  • write /путь/до/файла строка - записать строку в файл.

Шаг четвертый. Zygote и app_process

На определенном этапе загрузки init встретит в конце конфига примерно такой блок:

Service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class default socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd

Это описание службы Zygote, ключевого компонента любой Android-системы, который ответственен за инициализацию, старт системных служб, запуск и остановку пользовательских приложений и многие другие задачи. Zygote запускается с помощью небольшого приложения /system/bin/app_process, что очень хорошо видно на приведенном выше куске конфига. Задача app_proccess - запустить виртуальную машину Dalvik, код которой располагается в разделяемой библиотеке /system/lib/libandroid_runtime.so, а затем поверх нее запустить Zygote.

Когда все это будет сделано и Zygote получит управление, он начинает формирование среды исполнения Java-приложений с помощью загрузки всех Java-классов фреймворка (сейчас их более 2000). Затем он запускает system_server, включающий в себя большинство высокоуровневых (написанных на Java) системных сервисов, в том числе Window Manager, Status Bar, Package Manager и, что самое важное, Activity Manager, который в будущем будет ответственен за получение сигналов о старте и завершении приложений.

После этого Zygote открывает сокет /dev/socket/zygote и уходит в сон, ожидая данные. В это время запущенный ранее Activity Manager посылает широковещательный интент Intent.CATEGORY_HOME, чтобы найти приложение, отвечающее за формирование рабочего стола, и отдает его имя Zygote через сокет. Последний, в свою очередь, форкается и запускает приложение поверх виртуальной машины. Вуаля, у нас на экране появляется рабочий стол, найденный Activity Manager и запущенный Zygote, и статусная строка, запущенная system_server в рамках службы Status Bar. После тапа по иконке рабочий стол пошлет интент с именем этого приложения, его примет Activity Manager и передаст команду на старт приложения демону Zygote

INFO

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

В процессе загрузки Android отображает три разных загрузочных экрана: первый появляется сразу после нажатия кнопки питания и прошит в ядро Linux, второй отображается на ранних этапах инициализации и записан в файл /initlogo.rle (сегодня почти не используется), последний запускается с помощью приложения bootanimation и содержится в файле /system/media/bootanimation.zip.

Кроме стандартных триггеров, init позволяет определять собственные триггеры, которые могут срабатывать от самых разных событий: подключения устройства к USB, изменения состояния смартфона или изменения состояния системных переменных.

Кроме всего прочего, Activity Manager также занимается убийством фоновых приложений при нехватке памяти. Значения порогов свободной памяти содержатся в файле /sys/module/lowmemorykiller/parameters/minfree.

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

Во многом Android сильно отличается от других ОС, и с наскоку в нем не разобраться. Однако, если понять, как все работает, открываются просто безграничные возможности. В отличие от iOS и Windows Phone, операционка от гугла имеет очень гибкую архитектуру, которая позволяет серьезно менять ее поведение без необходимости писать код. В большинстве случаев достаточно подправить нужные конфиги и скрипты.

x86 .

Изначально разрабатывалась компанией Android Inc., которую затем (июль, 2005) купила Google. Впоследствии (ноябрь, 2007) Google инициировала создание бизнес-альянса Open Handset Alliance (в его состав вошли Google, HTC, Intel, Motorola, Nvidia и другие компании), который и занимается сейчас поддержкой и дальнейшим развитием платформы.

С момента выхода первой версии (сентябрь, 2008) произошло несколько обновлений системы. Эти обновления, как правило, касаются исправления обнаруженных ошибок и добавления нового функционала в систему. Каждая версия системы получает собственное кодовое имя на тему десерта.

1.2. Инструментарий разработчика

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

Как правило, разработка Android -приложений осуществляется на языке Java . Поэтому, в первую очередь , необходимо установить Java Development Kit ( JDK ). Но для начала следует разобраться, что представляет из себя Java .

Java – это объектно-ориентированный язык программирования . Программы на Java транслируются в байт-код, выполняемый виртуальной машиной Java , которая обрабатывает байтовый код и передает инструкции оборудованию как интерпретатор . Достоинство подобного способа выполнения программ заключается в полной независимости байт-кода от операционной системы и оборудования, что позволяет выполнять Java -приложения на любом устройстве, для которого существует соответствующая виртуальная машина . Другой важной особенностью Java является гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной. Любые операции , которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером) вызывают немедленное прерывание . Следует заметить, что фактически, большинство архитектурных решений, принятых при создании Java , было продиктовано желанием предоставить синтаксис , схожий с С/C++. В Java используются практически идентичные соглашения для объявления переменных, передачи параметров и операторов. Поэтому те, кто уже имеет опыт программирования на C/C++, смогут быстро освоиться и начать писать Java -приложения.

JDK – это бесплатно распространяемый комплект разработчика приложений на языке Java , включающий в себя компилятор Java , стандартные библиотеки классов Java , примеры, документацию, различные утилиты и исполнительную систему Java Runtime Environment ( JRE ). В состав JDK не входит интегрированная среда разработки (Integrated Development Environment ). Поэтому после того, как будет установлен JDK , следует установить IDE .

Существует несколько популярных сред разработки, но в данном курсе мы остановим свой выбор на Eclipse IDE и соответствующем для нее плагине Android Development Tools ( ADT ).

Android Software Development Kit ( SDK ) содержит множество инструментов и утилит для создания и тестирования приложений. Например, с помощью SDK Manager можно установить Android API любой версии (Рис. 1.1), а также проверить репозиторий на наличие доступных, но еще не установленных пакетов и архивов.


Рис. 1.1.

Android Native Development Kit (NDK) позволяет осуществлять разработку Android -приложений на языке C/C++. Зачем это может потребоваться? Есть несколько причин. Например, необходимость использовать код, который уже написан для нативной платформы, или ускорение выполнения критических кусков кода.

1.3. Архитектура Android

Рассмотрим основные компоненты операционной системы Android (Рис. 1.2).

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

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

Архитектура приложений разработана с целью упрощения повторного использования компонентов; любое приложение может "публиковать" свои возможности и любое другое приложение может затем использовать эти возможности (с учетом ограничений безопасности). Этот же механизм позволяет заменять стандартные компоненты на пользовательские.


Рис. 1.2.

Libraries. Android включает в себя набор C/C++ библиотек, используемых различными компонентами системы. Эти возможности доступны разработчикам в контексте применения Android Aplication Framework. Некоторые основные библиотеки, перечислены ниже:

  • Mедиа библиотеки – эти библиотеки предоставляют поддержку воспроизведения и записи многих популярных аудио, видео форматов и форматов изображений, в том числе MPEG4, MP3, AAC, AMR, JPG, PNG и других;
  • Surface Manager – управляет доступом к подсистеме отображения 2D и 3D графических слоев;
  • LibWebCore – современный веб-движок, на котором построен браузер Android;
  • SGL – основной графический движок 2D;
  • 3D библиотеки – реализованы на основе OpenGL; библиотеки используют либо аппаратное 3D-ускорение (при его наличии), либо включены программно;
  • FreeType – поддержка растровых и векторных шрифтов
  • SQLite – механизм базы данных, доступной для всех приложений.

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

Dalvik проектировалась специально под платформу Android . Виртуальная машина оптимизирована для низкого потребления памяти и работы на мобильном аппаратном обеспечении. Dalvik использует собственный байт-код. Android -приложения переводятся компилятором в специальный машинно-независимый низкоуровневый код. И именно Dalvik интерпретирует и выполняет такую программу при выполнении на платформе. Кроме того, с помощью специальной утилиты, входящей в состав Android SDK , Dalvik способна переводить байт-коды Java в коды собственного формата и также исполнять их в своей виртуальной среде.

Linux Kernel. Android основан на Linux версии 2.6 с основными системными службами – безопасность , управление памятью , управление процессами и модель драйверов. Разработчики Android модифицировали ядро Linux, добавив поддержку аппаратного обеспечения, используемого в мобильных устройствах и, чаще всего, недоступного на компьютерах.

1.4. Обзор Java-интерфейсов

Для прикладного программиста Android – это набор интерфейсов на языке Java . Рассмотрим, как он организован. В основе набора – пакеты, входящие в

Приложения для Android пишутся на языке программирования Java. Инструменты Android SDK (Software Development Kit – комплект разработки программного обеспечения) компилируют написанный вами код — и все требуемые файлы данных и ресурсов — в файл APK – программный пакет Android , который представляет собой файл архива с расширением.apk . В файле APK находится все, что требуется для работы Android-приложения, и он позволяет установить приложение на любом устройстве под управлением системы Android.

Каждое приложение Android, установленное на устройстве, работает в собственной "песочнице" (изолированной программной среде):

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

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

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

  • двум приложениям можно назначить один идентификатор пользователя Linux. В этом случае каждый из них сможет обращаться к файлам другого приложения. Для экономии ресурсов системы также можно сделать так, чтобы приложения с одинаковым идентификатором пользователя выполнялись в одном процессе Linux и использовали одну ВМ (приложения также должны быть подписаны одним сертификатом);
  • приложение может запросить разрешение на доступ к данным устройства, например к контактам пользователя, SMS-сообщениям, подключаемой карте памяти (SD-карте), камере, Bluetooth и др. Все разрешения должны предоставляться приложению при его установке.

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

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

Компоненты приложения

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

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

Четыре типа компонентов:

Операции Операция (Activity) представляет собой один экран с пользовательским интерфейсом. Например, в приложении для работы с электронной почтой одна операция может служить для отображения списка новых сообщений, другая – для составления сообщения и третья операция – для чтения сообщений. Несмотря на то что операции совместно формируют связное взаимодействие пользователя с приложением по работе с электронной почтой, каждая из них не зависит от других операций. Любые из этих операций могут быть запущены другим приложением (если это позволяет приложение по работе с электронной почтой). Например, приложение для камеры может запустить операцию в приложении по работе с электронной почтой, которая составляет новое сообщение, чтобы пользователь мог отослать фотографию.

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

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

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

Поставщики контента Поставщик контента (Content provider) управляет общим набором данных приложения. Данные можно хранить в файловой системе, базе данных SQLite, в Интернете или любом другом постоянном месте хранения, к которому у вашего приложения имеется доступ. Посредством поставщика контента другие приложения могут запрашивать или даже изменять данные (если поставщик контента позволяет делать это). Например, в системе Android есть поставщик контента, который управляет информацией контактов пользователя. Любое приложение, получившее соответствующие разрешения, может запросить часть этого поставщика контента (например ), для чтения и записи сведений об определенном человеке.

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

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

Приемники широковещательных сообщений Приемник широковещательных сообщений (Broadcast receiver) представляет собой компонент, который реагирует на объявления распространяемые по всей системе. Многие из этих объявлений рассылает система — например объявление о том, что экран выключился, аккумулятор разряжен или был сделан фотоснимок. Объявления также могут рассылаться приложениями, — например, чтобы сообщить другим приложениям о том, что какие-то данные были загружены на устройство и теперь готовы для использования. Несмотря на то что приемники широковещательных сообщений не имеют пользовательского интерфейса, они могут чтобы предупредить пользователя о событии "рассылка объявления". Однако чаще всего они являются просто "шлюзом" для других компонентов и предназначены для выполнения минимального объема работы. Например, они могут инициировать выполнение службой определенных действий при возникновении события.

Приемник широковещательных сообщений относится к подклассу класса , а каждое такое сообщение предоставляется как объект . Подробные сведения изложены в руководстве, посвященном классу .

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

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

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

Активация компонентов

Компоненты трех из четырех возможных типов — операции, службы и приемники широковещательных сообщений — активируются асинхронным сообщением, которое называется Intent (намерение). Объекты Intent связывают друг с другом отдельные компоненты во время выполнения, будь то это компоненты вашего или стороннего приложения (эти объекты Intent можно представить себе в виде мессенджеров, которые посылают другим компонентам запрос на выполнение действий).

Объект Intent создается с помощью объекта , который описывает запрос на активацию либо конкретного компонента, либо компонента конкретного типа — соответственно, намерение Intent может быть явным или неявным.

Для операций и служб Объект Intent определяет действие, которое требуется выполнить (например, просмотреть (view) или отправить (send) что-то), а также может указывать URI (Uniform Resource Identifier – унифицированный идентификатор ресурса) данных, с которыми это действие нужно выполнить (помимо прочих сведений, которые нужно знать запускаемому компоненту). Например, объект Intent может передавать запрос на выполнение операции "показать изображение" или "открыть веб-страницу". В некоторых ситуациях операцию можно запустить, чтобы получить результат. В этом случае операция возвращает результат также в виде объекта (например, можно отправить сообщение Intent, чтобы дать пользователю возможность выбрать контакт и вернуть его вам — в ответном сообщении Intent будет содержаться URI, указывающий на выбранный контакт).

Для приемников широковещательных сообщений Intent просто определяет передаваемое объявление (например, широковещательное сообщение о низком уровне заряда аккумулятора содержит только строку "аккумулятор разряжен").

Компоненты четвертого типа – поставщики контента – сообщениями Intent не активируются. Они активируются по запросу от . Процедура определения контента (content resolver) обрабатывает все прямые транзакции с поставщиком контента, с тем чтобы этого не пришлось делать компоненту, который выполняет транзакции с поставщиком. Вместо этого он вызывает методы для объекта . Это формирует слой, абстрагирующий (в целях безопасности) поставщика контента от компонента, запрашивающего информацию.

Для активации компонентов каждого типа имеются отдельные методы:

  • Можно запустить операцию (или определить для нее какое-то новое действие), передав объект методу или (если требуется, чтобы операция вернула результат).
  • Можно запустить службу (либо выдать работающей службе новые инструкции), передав объект методу . Либо можно установить привязку к службе, передав объект методу .
  • Можно инициировать рассылку сообщений, передав объект таким методам, как , и .
  • Можно выполнить запрос к поставщику контента, вызвав метод для объекта .

Подробные сведения об использовании объектов Intent приведены в документе . Более подробная информация об активации определенных компонентов также приведена в следующих документах: , и .

Файл манифеста

Для запуска компонента приложения системе Android необходимо знать, что компонент существует. Для этого она читает файл AndroidManifest.xml приложения (файл манифеста). В этом файле, который должен находиться в корневой папке приложения, должны быть объявлены все компоненты приложения.

Помимо объявления компонентов приложения, манифест служит и для других целей, среди которых:

  • указание всех полномочий пользователя, которые требуются приложению, например разрешения на доступ в Интернет или на чтение контактов пользователя;
  • объявление минимального , требуемого приложению, с учетом того, какие API-интерфейсы оно использует;
  • объявление аппаратных и программных функций, которые нужны приложению или используются им, например камеры, службы Bluetooth или сенсорного экрана;
  • указание библиотек API, с которыми необходимо связать приложение (отличные от API-интерфейсов платформы Android), например библиотеки Google Maps ;
  • и многое другое.

Объявление компонентов

Основная задача манифеста – это информировать систему о компонентах приложения. Например, файл манифеста может объявлять операцию следующим образом:

...

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

Объявление возможностей компонентов

Как уже говорилось в разделе , с помощью объекта можно запускать операции, службы и приемники широковещательных сообщений. Для этого в объекте Intent следует явно указать имя целевого компонента (с помощью имени класса компонента). Однако в полной мере возможности объектов Intent раскрываются при использовании концепции неявных Intent . В неявном сообщении Intent просто описывается тип действия, которое требуется выполнить (а также, хотя это и не обязательно, данные, в отношении которых вы бы хотели выполнить это действие). Системе же предоставляется возможности найти на устройстве компонент, который может выполнить это действие, и запустить его. При наличии нескольких компонентов, которые могут выполнить действие, описанное в сообщении Intent, пользователь выбирает, какой из них будет использоваться.

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

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

Например, если вы создали приложение для работы с электронной почтой с операцией составления нового сообщения, вы можете объявить фильтр для ответа на сообщения Intent типа "send" (для отправки нового сообщения электронной почты) следующим образом:

...

Затем, если другое приложение создаст объект Intent с действием и передаст его в , система сможет запустить вашу операцию, дав пользователю возможность написать и отправить сообщение электронной почты.

Подробные сведения о создании фильтров объектов Intent приведены в документе .

Объявление требований приложения

Существует огромное количество устройств, работающих под управлением Android, и не все они имеют одинаковые функциональные возможности. Чтобы ваше приложение не могло быть установлено на устройствах, в которых отсутствуют функции, необходимые приложению, важно четко определить профиль для типов устройств, поддерживаемых вашим приложением, указав требования к аппаратному и программному обеспечению в файле манифеста. Эти объявления по большей части носят информационный характер, система их не читает. Однако их читают внешние службы, например Google Play, с целью обеспечения фильтрации для пользователей, которые ищут приложения для своих устройств.

Например, если вашему приложению требуется камера и оно использует API-интерфейсы из Android 2.1 ( 7), эти параметры следует объявить в файле манифеста в качестве требований следующим образом:

...

Теперь ваше приложение нельзя будет установить из Google Play на устройствах, в которых нет камеры, а также на устройствах, работающих под управлением Android версии ниже 2.1.

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

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

Ресурсы приложения

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

Для каждого ресурса, включаемого в проект Android, инструменты SDK задают уникальный целочисленный идентификатор, который может использоваться, чтобы сослаться на ресурс из кода приложения или из других ресурсов, определенных в XML. Например, если в вашем приложении имеется файл изображения с именем logo.png (сохраненный в папке res/drawable/), инструменты SDK сформируют идентификатор ресурса под именем R.drawable.logo , с помощью которого на изображение можно будет ссылаться и вставлять его в пользовательский интерфейс.

Один из наиболее важных аспектов предоставления ресурсов отдельно от исходного кода заключается в возможности использовать альтернативные ресурсы для различных конфигураций устройств. Например, определив строки пользовательского интерфейса в XML, вы сможете перевести их на другие языки и сохранить эти переводы в отдельных файлах. Затем по квалификатору языка, добавленному к имени каталога ресурса (скажем res/values-fr/ для строк на французском языке), и выбранному пользователем языку система Android применит к вашему пользовательскому интерфейсу строки на соответствующем языке.

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

Предоставление ресурсов Описание структуры приложений Android, в которой ресурсы приложения существуют отдельно от его кода, а также сведения о том, как предоставлять альтернативные ресурсы для определенных конфигураций устройств.

Возможно, вас также заинтересует:

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