Когда-то давно, я тиснул пост «Нужны ли Андроиду киллеры? Окончательное решение вопроса» достаточно поверхностный. Но фундаментальные понятия нельзя описать просто двумя словами. И вот, спустя годы, на новом уровне Андроид программиста возвращаюсь к вопросу.

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

Оригинал здесь «Multitasking the Android Way».

Старший разработчик Android Диана Хакборн (Dianne Hackborn)

Старший разработчик Android Диана Хакборн (Dianne Hackborn)

Проектные требования

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

2. Мобильные устройства не могут позволить себе роскошь иметь диск подкачки, поэтому имеют довольно жесткие ограничения на использование памяти. Хорошая статья об этом : «Why the iPad and iPhone don’t Support Multitasking».

3. Скорость переключения между приложениями на мобильном устройстве крайне критична для пользователя. Разработчики Андроид поставили себе цель: мгновенно, менее чем за 1 секунду приложение должно заработать во что бы то ни стало. Это особенно важно, когда пользователь переключается между несколькими приложениями, например, чтобы посмотреть на новое SMS-сообщение во время просмотра видео, а затем нужно вернуться к видео. Заметное ожидание в таких ситуациях быстро заставит пользователей ненавидеть вас.

4. Доступные интерфейсы API должны быть достаточными для написания встроенных приложений Google, как часть философии «все приложения созданы равными». Это означает, что фоновое воспроизведение музыки, синхронизация данных, GPS навигация и загрузка приложений должны быть реализованы с помощью тех же API, которые доступны для сторонних разработчиков.

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

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

Когда приложение останавливается?

Распространенное недопонимание многозадачности Android лежит в отличие между процессом (process) и приложением (application). В Андроид они не являются тесно связанными сущностями.

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

Тот факт, что вы можете увидеть, что приложение «работает» (running) не означает, что приложение реально работает или делает что-либо. Просто система Андроид решила не убивать процесс, а оставить его на случай, если оно понадобится в будущем.

Читать ещё :   Эксклюзив. Гуглофону быть !

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

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

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

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

Если пользователь позже возвращается к приложению, которое было убито, Android’у нужен способ, чтобы повторно запустить его в том же состоянии, как это было в последний раз, чтобы соответствовать принципу «все приложения работают все время» (all applications are running all of the time). Это делается путем отслеживания частей пользовательского приложения (активностей), и вновь запуская их с информацией о последнем состоянии. Это последнее состояние генерируется каждый раз, когда пользователь покидает эту часть приложения (но не тогда, когда оно был убито).

Явная работа в фоновом режиме

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

Есть два основных средства: Broadcast Receivers и Services.

BroadcastReceiver

Широковещательные сообщения (BroadcastReceiver) позволяют приложению работать, в течение короткого промежутка времени, в фоновом режиме в результате определенного события. Он может быть использован многими способами при создании объектов более высокого уровня: например, AlarmManager позволяет приложению иметь широковещательную отправку в определенное время, и LocationManager может послать широковещательное сообщение, когда он обнаруживает интересные изменения в местоположении. Поскольку информация о приемнике является частью manifest, Android может найти и запустить приложение, даже если оно не работает; Конечно, если у него уже есть свой процесс доступный в фоновом режиме, широковещательное сообщение может очень эффективно послано непосредственно к нему.

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

Широковещательные сообщения (BroadcastReceiver) отлично подходят для небольших кусочков работы в ответ на внешнее событие, например, разместив уведомление пользователю после отправки нового отчета о местоположении GPS. Они очень легкие, так как процесс приложения должен только присутствовать пока активен BroadcastReceiver. Поскольку они являются активными в ограниченный период времени, достаточно сильные гарантии могут быть даны в том, что их процесс не будет убит во время выполнения. Однако BroadcastReceiver не подходят для задач неопределенной длительности, например работы с сетью.

Читать ещё :   Почему вы не должны использовать Task Killer в Android

Services

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

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

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

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

Встроенные компоненты

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

В Android 1.0 они были использованы для реализации почти всех фоновых задач:

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

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

  • методы ввода с использованием IME
  • виджеты
  • живые обои и др.

Послесловие

Читать дополнительно «Почему вы не должны использовать Task Killer в Android».

В дальнейших интервью с разработчиками платформы Диана Хакборн (Dianne Hackborn) на вопрос «что команда Android хотела бы сделать по-другому в самом начале развития платформы ?» отметила, что нужно было бы изначально обеспечить больший контроль платформы над приложениями, сильнее ограничить с точки зрения доступа к некоторым системным функциям.

Автор оригинальной статьи, как явствует из старой персональной странички «аля 90-е», является разработчиком Android платформы, музыкантом, садоводом, активисткой ЛГБТ сообщества, поклонницей BDSM.

Вот её авторская небольшая, но красноречивая иллюстрация к своему же  BDSM рассказу .

Story by Dianne Hackborn «The Claiming of Peaches»

Story by Dianne Hackborn «The Claiming of Peaches»