11 февраля 2013

[Конкурс] По ту сторону экрана (анатомия программ)

Все знают, что программы для ОС Android заключены в контейнер apk — файлы именно с таким расширением скачиваются из Google Play. Но что собой представляет программа, сложно ли её написать, какие шестерёнки заставляют на экране телефона крутиться стрелки виджета часов? Вот об этом и пойдёт речь в данной статье.

Несколько вводных слов

Ядро операционной системы Android основано на Linux и написано на языке программирования C (си). Скомпилированные исполняемые файлы ядра представляют собой нативный код — то есть непосредственно команды ARM-процессора. Однако всё пользовательское ПО и значительная часть системного пишется на объективно-ориентированном языке Java. Скомпилированные файлы Java – это уже не нативный, а специальный байт-код, который требует интерпретации и выполняется в виртуальной машине Дальвик (Dalvik Virtual Machine), названной в честь исландского городка Дальвик, в котором жили предки Дэна Борнштейна – создателя виртуальной машины. Таким образом, программы для ОС Android требуют перед запуском интерпретации, что приводит к большей загруженности процессора и большему потреблению оперативной памяти. Но на другой чаше весов лежат неоспоримые преимущества: лёгкость создания программ, переносимость кода, отсутствие привязки к конкретному железу. В результате для платформы Android имеется огромное количество самых разнообразных приложений, что связано не в последнюю очередь с простотой их написания.

Сложно ли создать стрелочные часы в Android?

Вы не поверите, но для создания таких часов не нужно писать ни одной строчки java-кода! В ADT (Android Development Tools — Средства разработки Android) уже есть стандартный класс AnalogClock, которому нужно лишь указать три своих картинки: циферблат, минутную и часовую стрелки — система сама повернёт стрелки на нужный градус и будет обновлять графику каждую минуту. Так что не стоит удивляться, что для Android существует такое множество часов самых разнообразных раскрасок. Но с другой стороны простота программирования выливается в большое количество похожих и неоригинальных программ.

Кстати!..
В Android нет стандартного приложения «часы». Есть штатный экран настроек, на котором задаются дата, время, часовой пояс и так далее, а программа, показывающая текущее время, не входит в состав ОС. Именно поэтому большинство часовых виджетов некликабельны — нет простого и надёжного способа узнать, какую программу следует запустить на конкретном устройстве.

Анатомия apk файла

Apk файл имеет контейнерную структуру и включает в себя набор папок и файлов. Среди них особо стоит отметить AndroidManifest.xml: в нём содержатся все необходимые операционной системе данные о программе: её название, иконка, категория (например, категория HOME — программа, вызываемая кнопкой «домик»), список требуемых разрешений и т.д.

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

Помимо манифеста, контейнер apk содержит скомпилированные файлы java — это, собственно, и есть программа со всеми её алгоритмами — и файлы ресурсов. Последние включают в себя графику и таблицы xml, в которых содержатся описания экранных элементов (кнопки, текстовые поля и т.д.), описания меню, список строковых констант и прочее. Ресурсы в Android имеют чёткую иерархию: графические файлы содержатся в папке drawable, описания экранных элементов — в папке layout, список констант — в папке values и так далее. У каждой из папок могут быть клоны: к названию папки прибавляется специальный суффикс, указывающий, что внутри содержатся альтернативные ресурсы — для другого размера и разрешения экрана, например. Это позволяет программе адекватно выглядеть на самых разных устройствах.

Кстати!..
Линейные размеры в Android задаются в условных пиксельных единицах — dp (он же dip — device independent pixel — независимый от устройства пиксел). Можно, конечно, указать и в физических точках экрана — но настоятельно не рекомендуется этого делать. Один dp будет превращаться в разное количество реальных точек в зависимости от пиксельной плотности экрана dpi (dots per inch — количество точек на дюйм). Так, например, для пятидюймового экрана с разрешением HD (720×1280) один dp будет равен двум реальным пикселам, а для экрана 3,2″ с разрешением 320×480 — одному пикселу. В итоге кнопка, заданная как 100×40 dp, будет на этих разных экранах иметь примерно одинаковый размер – как раз под удобное нажатие пальцем.

Ещё одно важное преимущество такого подхода к ресурсам — простота реализации поддержки разных языков. В apk контейнере может быть несколько файлов strings.xml, содержащих строковые константы на английском, русском, китайском и т.д. — операционная система выберет тот, который соответствует установленному на устройстве языку.

Как работает программа?

Когда вы кликаете по ярлыку программы на рабочем столе или в меню установленных приложений, операционная система из соответствующего файла-манифеста извлекает название главной activity (перевод: активность, деятельность) и запускает её. Activity — это основополагающий элемент программы — по сути, экранное полотно, на котором выводится какая-либо информация (эквивалент окна в ОС Windows). В программе может быть несколько activity: одна запускается при старте приложения и содержит, например, список писем, другая — показывает выбранное письмо, а ещё есть activity с настройками. То есть работа программы заключается в смене этих самых activity в зависимости от того, какие действия предпринял пользователь.

Activity запускаются в стеке: текущая переводится в режим останова и не выгружается из памяти, а активной становится новая. Когда пользователь нажимает кнопку «Назад», последняя — на вершине стека — activity уничтожается, а предыдущая вновь становится активной; за счёт этого переход назад производится очень быстро. Но особенность ОС Android заключается в том, что видимая, но неактивная activity находится в режиме паузы и не обновляется. Например, в ОС Windows есть целый набор методов для частичного обновления окна – операционная система указывает программе ту область экрана, которую нужно отрисовать; в Android ничего подобного нет. В результате получается, что если находящаяся на вершине стека activity обладает прозрачным фоном, то вид застывшего предыдущего экрана в некоторых случаях может выглядеть странно и непривычно. Так что очень даже неспроста при показе всплывающих диалоговых окон используется тотальное затемнение прозрачного фона. Многие считают, что этот феномен в ОС Android является признаком неполноценной многозадачности, но на самом деле это особенность жизненного цикла activity — особенность дизайна системы.

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

Кстати!..
Если во время перестроения коснуться экрана, операционная система запомнит этот факт и передаст его в новосозданную activity; при этом пользователь обнаружит такой глюк: касание было в один экранный элемент, а сработает — другой. Или не сработает вовсе — если по координате касания в новой activity не будет кликабельной области.

Другой особенностью ОС Android является то, как разные программы и activity взаимодействуют друг с другом: это осуществляется при помощи специальных посылок, которые называются intent (перевод: намерение). То есть, когда пользователь нажал на элемент из списка писем и нужно открыть и показать выбранное письмо, текущая activity отсылает операционной системе intent, в котором указывает, что нужно запустить такую-то activity, а также добавляет в intent данные — в нашем случае это идентификатор письма, которое должно быть отображено новой activity. Преимущество интентной переписки заключается в том, что можно единообразным способом запрашивать самые различные действия. Например, activity может направить операционной системе такое послание: «мне нужно, чтобы пользователь выбрал картинку». И система ищет среди установленных приложений те, которые реализуют интерфейс выбора графического файла (об этом указано в их манифесте – на какие запросы приложение умеет отвечать). Если подходящих программ окажется несколько, то пользователю будет предложено выбрать одну из них — наверное, все уже видели это всплывающее окно: «Выполнить действие с помощью”.

Также в интентах можно использовать URI (Uniform Resource Identifier — унифицированный идентификатор ресурса). URI — это символьная строка, позволяющая идентифицировать какой-либо ресурс: документ, изображение, файл, службу, ящик электронной почты и т.д. Например, в ответ на запрос с URI-строкой «tel:1234567» операционная система запустит приложение «телефон» и укажет ему номер 1234567, а на запрос с URI-строкой «geo:55.751666,37.617777» откроется приложение «карты» и покажет то, что находится по указанным координатам.

Кстати!..
Частный случай URI — это URL (Uniform Resource Locator — единообразный локатор ресурса), при помощи которого адресуются вэб-страницы в сети Интернет и иные ресурсы. Так что в ответ на интент с URI-строкой «https://android.mobile-review.com» будет запущен браузер, который покажет соответствующий сайт.

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

Собственно, на этом всё!

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

29 комментариев на «“[Конкурс] По ту сторону экрана (анатомия программ)”»

  1. Креативный пингвин:

    Достаточно интересно и необычно. Никто о таком здесь еще не писал, автор молодец)

  2. $22471748:

    Достаточно интересно, но абсолютно бесполезно для рядового пользователя. Ему не с чем сравнить выкладки автора и сделать какие-либо выводы. Статья не содержит ничего конкретного. Например статья, описывающая по шагам создание виджета — цифровые часы ( к примеру) для андроид, произвела бы фурор. А эта статья из серии бла-бла-бла. Ну лично для меня.

  3. zlotin:

    Уж извините, но в одной статье Вы попытались объять необъятное.Получилось как-то смазано, что-ли…

  4. anonimNO:

    А мне было интересно, спасибо.

  5. Ztaz:

    Интересно! Но конечно многим будет «МНОГО БУКФФ» )

  6. Максим:

    Спасибо. Было очень интересно прочитать, позновательно.

  7. Статья интересная. Несмотря на «многабукаф» прочитать полностью не составило никакого труда.
    Теперь немного покритикую:

    1) раздел «Сложно ли создать стрелочные часы в Android?» я бы убрал, он здесь ни к чему. А лучше бы не удалил, а перенёс в отдельную статью с описанием как создавать такие — думаю статья была бы весьма популярной.
    2) на мой взгляд стоило бы поподробнее разъяснить некоторые понятия: например что такое стек и принципы его работы. Так же чуть побольше бы расписал о виртуальной машине dalvik (хотя и так написано нормально).
    3) Вы отлично описали Activity, от чего то совершенно забыли про Services. А на мой взгляд это довольно важно и добавило бы вашей статьи практичности (можно было бы указать почему применение тасккиллеров не несёт особой пользы и может даже принести вред).

  8. аноним:

    Интересно. Пиши вторую часть углубленную.

  9. Денис Васильев:

    Весьма интересная статья! Хорошо и грамотно написана, читается на одном дыхании. Вот только заканчивается как-то внезапно. Если бы поподробнее написать про принципы работы приложений в андроиде, распределение памяти, службы и таск-киллеры, я бы однозначно отдал такой статье первое место. Жаль, что я тут ничего не решаю… 🙂

  10. TimeS:

    Спасибо за статью =)

  11. Кашин Александр:

    Хорошая статья

  12. Dreamer...:

    >>>В Android нет стандартного приложения “часы”.

    Как это нет? А это что?

    • Сразу видно дизайнера, даже простой скрин хорошо сделан ))))

    • Stanislas:

      Я так понимаю, что скриншот сделан на Нексусе? Так вот, этого конкретного приложения от Гугла не будет на Самсунге, Сони, HTC… — там будут свои «Часы» и у них будут свои package name.

      • Dreamer...:

        Я и говорю в стандартной поставке Андроид ОС есть приложение «Часы» изначально.
        А вот то, что вендоры заменяют своими аппликухами стандартные приложения — меня искренне печалит.
        Не буду скрывать — я приверженец «Ванильного» андроида. )))

  13. Dreamer...:

    >>>В результате получается, что если находящаяся на вершине стека activity обладает прозрачным фоном, то вид застывшего предыдущего экрана в некоторых случаях может выглядеть странно и непривычно. <<<

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

    • Stanislas:

      Есть живые обои, как фон внутри одной activity — например, так сделаны обои в программе домашнего экрана. В статье же говорится об activity с прозрачным фоном, через который просвечивает другое раннее запущенное приложение.
      В принципе можно сделать приложение-окно, которое будет располагаться поверх всего остального и не блокировать ни обновления графики, ни перехватывать клики и свайпы — но это не рядовой случай. Так сделано, например, на Samsung Galaxy S3 маленькое окно с видео.

  14. Dreamer...:

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

  15. Stanislas:

    Общий ответ
    Всем спасибо за комментарии!
    Данная статья — изложение некоторых интересных фактов, связанных с
    особенностями создания программ и их работы на устройстве, — и не более
    того.
    Я не считаю, что android.mobile-review — это сайт, на котором стоит размещать уроки программирования под Android. Тем более что в Интернете полно ресурсов, в том числе и русскоязычных, посвящённых вопросам программирования, — где-то там есть и подробное описание того, как создать виджет часов, и ещё много чего прочего. Посмотрите startandroid.ru, например.
    Почему так неожиданно заканчивается статья? Ну, так получилось. Я не профессионал в деле написания статей.
    О программировании под Android можно много чего написать — и про сервисы, и про таски, и про виджеты; но стоит ли углубляться в такие дебри, если большинству посетителей сайта это не будет интересно? По-моему — не стоит; вполне достаточно упомянуть несколько любопытных особенностей, несколько общих слов а ля Википедия — и не лезть в болото.

    • Что конкретно из Android разработок было поглощено и разработано вами? Продукты какой категории, имиджа и стиля интересны лично вам?

      • Stanislas:

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