Оптимизация загрузок для эффективного доступа к сети

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

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

Состояния беспроводных сетей

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

Типичная 3G сеть имеет три энергетических состояния:

  1. Полная мощность: Используется, когда соединение активно, что позволяет устройству передавать данные на максимально возможной скорости.
  2. Малая мощность: Промежуточное состояние, которое использует около 50% заряда батареи по сравнению с полной мощностью.
  3. Ожидание: Минимальное потребление энергии, в течение которого сетевое соединение не активно или не требуется.

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

Чтобы свести к минимуму задержки, используется задержка, чтобы отложить переход к более низкому энергетическому состоянию. Рисунок 1 использует временные интервалы AT&T для типичной 3G сети.

Рисунок 1. Состояния типичный 3G беспроводной сети.

Состояния на каждом устройстве, в частности, задержки связанные с переходами между состояниями и задержки запуска, будут меняться в зависимости от используемой технологии беспроводной сети (2G, 3G, LTE и т.д.) и определяться настройками оператора сети, с которой работает устройство.

Этот урок описывает состояния типичной беспроводной 3G сети, на основе данных, предоставленных AT&T. Тем не менее, общие принципы и рекомендации применимы для всех реализаций беспроводных сетей.

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

К сожалению, такой подход может быть неэффективным для приложений на современных ОС смартфонов, таких как Android, где приложения работают как на переднем плане (где важна задержка) и в фоновом режиме (где время работы от батареи должно быть более приоритетным).

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

Каждый раз, когда вы создаете новое сетевое подключение, происходит переключение на полную мощность. В случае типичного подключения к 3G сети, описанной выше, сеть будет работать на полной мощности в течение всей передаче данных — плюс дополнительные 5 секунд до перехода к пониженному энергопотребления — за которым следуют 12 секунд до перехода в состояние ожидания. Таким образом, для типичного 3G устройства, каждый сеанс передачи данных приведет к тому, что сеть будет использовать энергию в течение почти 20 секунд.

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

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

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

Рисунок 2. Относительное использование энергии батареи беспроводной сетью для пакетной и раздельной передаче данных.

Предварительная выборка данных

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

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

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

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

Как агрессивно использовать предварительную выборку зависит от размера загружаемых данных и вероятности их использования. В качестве приблизительного руководящего принципа, основанного на состояниях описанных выше, для данных, которые имеют 50% шансы быть использованными в текущей сессии пользователя, как правило, можно выполнять предварительную выборку в течение приблизительно 6 секунд (примерно 1-2 Мб) пока потенциальная стоимость загрузки неиспользуемых данных соответствует потенциальной экономии, если не загружать данные, которые понадобятся.

Вообще говоря, хорошая практика выполнять предварительную выборку данных, для загрузки которых вам нужно будет инициировать другое соединение каждые 2-5 минут, для заргузки от 1 до 5 мегабайт.

Следуя этому принципу, объемные загрузки — такие как видео файлы — должны загружаться по кускам через равномерные промежутки времени (каждые 2-5 минут), загружая только видеоданные, которые, вероятно, будут просматриваться в ближайшие несколько минут.

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

Давайте посмотрим некоторые практические примеры:

Музыкальный плеер

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

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

Чтение новостей

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

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

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

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

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

Пакетная передача данных и соединения

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

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

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

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

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

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

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

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

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

Уменьшение подключений

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

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

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

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

Использование инструментов отслеживания сетевого трафика DDMS для определения проблемных областей

Android DDMS (Dalvik Debug Monitor Server - Dalvik Сервер Отслеживания и Отладки ) включает в себя Вкладку подробной сетевой статистики, которая позволяет отслеживать, когда приложение выполняет сетевые запросы. Используя этот инструмент, вы можете проследить, как и когда приложение передает ваши данные и оптимизировать исходный код соответствующим образом.

На рисунке 3 показан пример передачи небольших объемов данных примерно 15 секунд друг от друга, предполагая, что эффективность может быть значительно улучшена путем предварительной выборки и пакетизации данных.

Рисунок 3. Отслеживание использования сети с помощью DDMS.

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

Чтобы лучше определить причину "шипов", API статистики сетевого трафика позволяет помечать передачи данных, происходящие в потоке с помощью TrafficStats.setThreadStatsTag() метода, с последующей пометкой вручную отдельных сокетов с помощью tagSocket() и untagSocket(). Например:

TrafficStats.setThreadStatsTag(0xF00D);
TrafficStats.tagSocket(outputSocket);
// Transfer data using socket
TrafficStats.untagSocket(outputSocket);

Apache HttpClient и URLConnection библиотеки автоматически помечают сокеты на основе текущего значения getThreadStatsTag() . Эти библиотеки помечают также сокеты при повторном использовании их из пулов.

TrafficStats.setThreadStatsTag(0xF00D);
try {
  // Make network request using HttpClient.execute()
} finally {
  TrafficStats.clearThreadStatsTag();
}

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