Defrider
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Многозадачность в Android Android достаточно уникален в способе организации одновременной работы нескольких приложений. Разработчики пришедшие с других платформ, могут быть удивлены тем, как это работает. Понимание этого важно для разработки хорошо работающих приложений и их бесшовной интеграции с остальной частью платформы Android. В этой статье рассматриваются причины такого подхода к многозадачности, его влияния на работу приложений, и как лучше всего воспользоваться уникальными возможности платформы. Проектные требования Мобильные устройства имеют ряд технических ограничений и пользовательских требований, несвойственных настольным или вэб системам. Ниже четыре ключевых ограничения, надо которыми мы работали в процессе разработки многозадачности в Android: * Мы не хотим требовать от пользователя, чтобы он каждый раз закрывал приложения после того как закончит с ним работать. Подобное плохо работает в мобильной среде, где имеют место повторяющиеся в течение дня кратковременные взаимодействия с широким спектром приложений. * Мобильные устройства не могут себе позволить роскошь подкачки, поэтому они имеют довольно жёсткие ограничения на использование памяти. Robert Love написал очень хорошую статью на эту тему. * Переключение приложений на мобильных устройствах очень критично. Мы нацелены на то, чтобы запуск новых приложений происходил менее чем за одну секунду. Это особенно важно, например, в случае, когда пользователь решает во время просмотра видео прочитать новое SMS, а затем вновь возвращается к просмотру. Заметное ожидание в данном случае вызвало бы гнев пользователей. * Доступные программные интерфейсы должны быть достаточными для написания встроенных приложений в рамках нашей философии «все приложения созданы равными». Это означает, что фоновое воспроизведение музыки, синхронизация данных, GPS навигация и загрузка приложений должны быть реализованы с помощью тех же программных интерфейсов, что и приложения сторонних разработчиков. Первые два требования конфликтуют между собой. Мы не хотим чтобы пользователь заботился о закрытии свои приложений, наоборот мы хотим создать видимость, что все приложения всегда запущены. В то же время мобильные устройства имеют жёсткие ограничения на использование памяти, поэтому система начнет очень быстро деградировать как только ей понадобится больше памяти, чем доступно; в отличие от настольного компьютера, который слегка замедлится во время сброса страницы памяти в файл подкачки. Эти конкурирующие ограничения были главным стимулом для разработки Android. В какой момент приложение «останавливается»? Источник заблуждений относительно многозадачности в Android кроется в различии процесса и приложения. В Android они не являются тесно связанными сущностями: приложение может казаться запущенным даже при отсутствии процесса; несколько приложений могут использовать один процесс или одно приложение может использовать несколько процессов; процессы могут присутствовать в системе даже если их приложения бездействуют. Даже если вы видите, что процесс приложения «работает», это не означает что приложение запущено или что-нибудь выполняет. Такое может случится, например, из-за того, что Android иногда нуждается в этом приложении и поэтому решил что лучше будет держать его под рукой на случай если оно вновь понадобится; или же, если вы покинули приложение не надолго, чтобы позже вернуться к нему, а системе в этом время понадобилось освободить процесс для других целей. Ключом к тому, как Android обрабатывает приложения таким образом является то, что процессы не уничтожаются полностью. Когда пользователь покидает приложение, его процесс переводится в фоновый режим, позволяя процессу продолжить свою работу (например, загрузку web страниц) если это требуется. А когда пользователь возвращается в приложение, его процесс переводится в активное состояние. Если устройство не имеет проблем с недостатком памяти, то Android будет держать все эти процессы под рукой, а приложения будут действительно (а не мнимо) «работать». Так как объём памяти является ограниченным, Android должен решить когда избавляться от ненужных процессов. Это приводит к понятию жизненного цикла процессов и правилам, которые используются для того чтобы определить на сколько важен каждый процесс и какой из них может быть уничтожен. Эти правила основаны на том, на сколько важен процесс для пользователя, а также на том, когда в последний раз процесс требовался ему. Если Android определяет, что процесс можно уничтожить, то он просто принудительно убивает его. При этом ядро может незамедлительно освободить все ресурсы используемые этим процессом, не рассчитывая на то, что приложение хорошо написано и само освободит все свои ресурсы в ответ на завершение. Такое поведение ядра позволяет избежать серьезных проблем с нехваткой памяти. Если пользователь позже решит вернуться к убитому приложению, системе потребуется способ заново запустить его в том же состоянии, в котором оно было до того, как его убили, дабы сохранить видимость, что все приложения всегда запущены. Это делается путём отслеживания частей приложения (Activities) с которыми взаимодействовал пользователь и последующим их перезапуском с информацией о последнем состоянии. Последнее состояние генерируется каждый раз, когда пользователь покидает Activity, а не тогда, когда приложение убивается. Поэтому ядро может свободно убить приложение, не заботясь о корректности завершения приложения. В некотором смысле такое управление процессами можно рассматривать как одну из форм подкачки: процессы приложений представляют собой некоторый объём используемой памяти; при нехватке памяти некоторые процессы могут быть уничтожены (сброшены); когда эти процессы вновь понадобятся, они могут быть восстановлены в последнем сохранённом состоянии (извлечены). Реальное исполнение в фоновом режиме Итак, приложение может находится в фоновом режиме, до тех пор пока оно не будет убито системой в рамках правил управления памятью. Это приемлемо для таких вещей как загрузка вэб страниц в фоновом режиме, но что на счёт вещей с более жесткими требованиями: фоновое воспроизведение музыки, отслеживание местоположения, будильник и т.д.? Для таких задач приложению доступны два основных средства: broadcast receivers и службы. Broadcast Receivers Broadcast receivers позволяют приложению выполнять действия в фоновом режиме в течение короткого промежутка времени. Они могут быть использованы для создания средств более высокого уровня. Например, AlarmManager позволяет послать broadcast в определённое время в будущем, LocationManager посылает broadcast если зафиксирована смена местоположения. Поскольку информация о приёмнике является частью манифеста, Android может найти и запустить связанное с ним приложение, если оно не запущено. Если процесс приложения находится в фоновом режиме, то broadcast направляется непосредственно в него. Приложение имеет ограниченное время для его обработки (10 секунд). В случае если обработка не укладывается в это время, тогда приложение считается не совсем корректным и его процесс вновь переводится в фоновый режим для того чтобы быть уничтоженным в случае необходимости. Broadcast receivers хорошо подходят для проделывания небольшой работы в ответ на внешние возбуждающие факторы. Например, отправление уведомления пользователю в ответ на получение новых GPS координат. Они потребляют очень мало ресурсов, так как требуют действий от приложения лишь во время приёма broadcast'a. Поскольку они существуют в течение ограниченного интервала времени, то гарантировано, что их процесс не будет уничтожен во время исполнения. Однако они не подходят для выполнения действий неопределенной длительности, например работы с сетью. Службы Службы позволяют приложениям выполнять продолжительные по времени операции. Существует много других функций, которые выполняют службы, но в контексте данной статьи их главную цель можно выразить словами «Эй, я хотел бы исполнятся даже находясь в фоновом режиме, и до тех пор пока я не скажу хватит». Приложение управляет работой своих служб с помощью команд запуска и остановки. Хотя службы предоставляют богатую клиент-серверную модель, её использование не является обязательным. Во время запуска службы, Android создаёт её объект в процессе приложения для обеспечения доступа к контексту. Как это может быть использовано приложением: оно может поместить весь требуемый код внутри своей службы без взаимодействия с другими частями приложения; может вызывать общие объекты-синглтоны, получив экземпляр службы из любого места; или же запустить службу в отдельном процессе и реализовать полноценный RPC протокол если потребуется. Управление процессами служб отличается от управления процессами broadcast reciever'ов, поскольку неограниченное число служб может выполняться неопределенно долго по времени. Из-за этого могут возникнуть проблемы с нехваткой памяти. По этой причине нет гарантий, что система их не остановит. При нехватке памяти процессы служб будут немедленно уничтожены, подобно тому как уничтожаются процессы находящиеся в фоновом режиме. Но тем не менее, Android запомнит, что эти службы хотели бы выполнятся дальше, и перезапустить их, когда памяти будет достаточно. Например, если пользователь откроет web страницу требующую много памяти, Android может уничтожить процесс такой службы как sync, а когда памяти станет достаточно — перезапустит его. Чтобы не быть уничтоженными в таких случаях, службы могут запросить статус «foreground». Этим они как бы говорят «пожалуйста, не убивайте меня». Но для этого требуется, чтобы службы уведомляли пользователя о своей работе. Это полезно для таких служб как фоновое проигрывание музыки или автомобильная навигация с которыми пользователь активно взаимодействует; когда вы слушаете музыку и используете браузер, вы всегда можете видеть значок воспроизведения музыки на панели состояния. Android не будет пытаться уничтожить такие службы, если точно знает что пользователь уведомляется об их работе и может в любое время их остановить. Ценность базовых компонентов Broadcast receiver'ы и службы позволяют разработчикам создавать операции, которые будут выполнятся в фоновом режиме. Включая такие операции, для которых они изначально не разрабатывались. В Android 1.0 они использовались практически для всех фоновых операций встроенных Google приложений: * Воспроизведение музыки осуществляется службой. Это позволило не прерывать воспроизведение после того пользователь покинет приложение для воспроизведения музыки. * Приложение будильник планирует свои сигналы с помощью broadcast reciever'a и alarm manager'a. * Приложение календарь, подобно будильнику, отображает или обновляет уведомления, соответствующие времени определённого события. * Фоновая загрузка файлов реализована в виде службы, которая запускается для обработки закачек. * Приложение электронной почты будит службу проверки почты через определенные интервалы времени для получения новых писем. * Приложения Google поддерживают службу получения уведомлений из сети. Которая в свою очередь перенаправляет запросы к конкретным приложениям, например, для того чтобы синхронизировать контакты. В процессе развития платформы эти компоненты использовались для разработки многих основных вещей: * Методы ввода реализованы как службы, с которыми работает и которыми управляет Android для отображения редактора ввода. * Виджеты приложений являются broadcast reciever'ами, которым Android посылает запрос, если хочет взаимодействовать с ними. Это делает виджеты достаточно легковесными и позволяет им не заботится о том, чтобы процесс приложения был запущен. * Специальные возможности реализованы в виде служб, которым Android посылает информацию о действиях пользователя. * Sync adapter'ы представленные в Android 2.0 являются службами работающими в фоновом режиме, которые выполняют синхронизацию данных. * Живые обои представляют собой службы запускаемые Android'ом. Оригинал статьи: http://android-developers.blogspot.com/2010/04/multitasking-android-way.html Перевод: afybc | Всего записей: 603 | Зарегистр. 31-03-2006 | Отправлено: 02:28 21-09-2011 | Исправлено: Defrider, 02:31 21-09-2011 |
|